天天看点

Silverlight_Rest_WCF系列之三:PUT和DELETE

我们在上篇文章中讲过WebClient不支持PUT,DELETE.

那么WebRequest支持PUT和DELETE吗??

于是我们修改PUT代码为:

WebRequest webRequest = WebRequest.Create("http://localhost:19598/ProductService.svc/Product");

            webRequest.ContentType = "application/json";

            webRequest.Method = "PUT";

结果还是一样的错误,细心的读者如果反编译过WebClient的话,可以看到内部的实现就是:

<a></a>

// System.Net.WebClient

using System;

protected virtual WebRequest GetWebRequest(Uri address)

{

    WebRequest webRequest = WebRequest.Create(address);

    this.CopyHeadersTo(webRequest);

    HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;

    。。。

    return webRequest;

}

原来WebClient不支持PUT和DELETE是因为WebRequest.Create(address)返回的WebRequest不支持PUT和DELETE啊。

事到如今摆在面前有两个方案。。

1:不支持就不要用它,就简单的用GET,POST两个Method就好了,用URL来区别就可以了,比如

<a href="/">http://...createproduct/</a>

<a href="/">http://...deleteproduct/</a>

2:试试还有没有其他的WebRequest支持PUT,DELETE,比如HttpWebRequest,。

当然了用1方案的没任何问题,用2方案的就要google下了。

在Silverlight中使用WebRequestCreator就可以设置PUT,DELETE了。

WebRequest webRequest =WebRequestCreator.ClientHttp.Create(

                new Uri("http://localhost:19598/ProductService.svc/Product"));

于是将PUT的代码修改为:

#region 使用WebRequest

            WebRequest webRequest =WebRequestCreator.ClientHttp.Create(

            webRequest.BeginGetRequestStream(requestAsyncCallback =&gt;

                {

                    Stream requestStream = webRequest.EndGetRequestStream(requestAsyncCallback);

                    JsonObject jo = new JsonObject();

                    jo["Id"] = Guid.NewGuid().ToString();

                    jo["Name"] = "test";

                    string jsonString = jo.ToString();

                    byte[] buffer = System.Text.Encoding.Unicode.GetBytes(jsonString);

                    requestStream.Write(buffer, 0, buffer.Length);

                    requestStream.Close();

                    webRequest.BeginGetResponse(responseAsyncCallback =&gt;

                        {

                            WebResponse webResponse = webRequest.EndGetResponse(responseAsyncCallback);

                            using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))

                            {

                                string result = reader.ReadToEnd();

                                MessageBox.Show(result);

                            }

                        }, null);

                }, null);

            #endregion

这里还是会抛出SecurityException。主要原因是PUT和DELETE操作需要服务端授权,于是将

clientaccesspolicy.xml的代码修改为:

&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;access-policy&gt;

  &lt;cross-domain-access&gt;

    &lt;policy&gt;

      &lt;allow-from  http-methods="*" http-request-headers="*"&gt;

        &lt;domain uri="*"/&gt;

      &lt;/allow-from&gt;

      &lt;grant-to&gt;

        &lt;resource path="/" include-subpaths="true"/&gt;

      &lt;/grant-to&gt;

    &lt;/policy&gt;

  &lt;/cross-domain-access&gt;

&lt;/access-policy&gt;

主要是设置&lt;allow-from  http-methods="*" http-request-headers="*"&gt;.

ok,我们再次尝试调用PUT。

在MessageBox.Show(result);这句代码抛出异常,异常为跨线程访问无效。

在silverlight中创建UI控件的是一个线程,也叫做UI线程,

silverlight使用其他的线程异步的调用服务,然后在其他的线程中尝试调用UI线程的MessageBox.Show,

针对跨线程访问无效有两种通用的方法。

1:使用Dispatcher对象。

2:使用System.Threading.SynchronizationContext对象保存线程的同步上下文.

在这里为了方便,我就直接

this.Dispatcher.BeginInvoke(() =&gt;

                                {

                                    MessageBox.Show(result);

                                });

 好了,今天就到此为止,下篇文章要封装调用Rest服务的方式,毕竟不可能每次调用服务都Copy这么多代码吧,下回分解。。

本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/05/09/2041516.html,如需转载请自行联系原作者