我們在上篇文章中講過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 =>
{
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 =>
{
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的代碼修改為:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-methods="*" http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
主要是設定<allow-from http-methods="*" http-request-headers="*">.
ok,我們再次嘗試調用PUT。
在MessageBox.Show(result);這句代碼抛出異常,異常為跨線程通路無效。
在silverlight中建立UI控件的是一個線程,也叫做UI線程,
silverlight使用其他的線程異步的調用服務,然後在其他的線程中嘗試調用UI線程的MessageBox.Show,
針對跨線程通路無效有兩種通用的方法。
1:使用Dispatcher對象。
2:使用System.Threading.SynchronizationContext對象儲存線程的同步上下文.
在這裡為了友善,我就直接
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(result);
});
好了,今天就到此為止,下篇文章要封裝調用Rest服務的方式,畢竟不可能每次調用服務都Copy這麼多代碼吧,下回分解。。
本文轉自LoveJenny部落格園部落格,原文連結:http://www.cnblogs.com/LoveJenny/archive/2011/05/09/2041516.html,如需轉載請自行聯系原作者