天天看點

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,如需轉載請自行聯系原作者