zoukankan      html  css  js  c++  java
  • 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的话,可以看到内部的实现就是:

    // 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来区别就可以了,比如

    http://...createproduct/

    http://...updateproduct/,

    http://...deleteproduct/

    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(
                    
    new Uri("http://localhost:19598/ProductService.svc/Product"));
                webRequest.ContentType 
    = "application/json";
                webRequest.Method 
    = "PUT";
                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);
                                    });

     完整源码:/Files/LoveJenny/2011-05-09/RestWCF.rar

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

  • 相关阅读:
    C#中的委托,匿名方法和Lambda表达式
    Java 8 Lambda表达式探险
    Lambda表达式有何用处?如何使用?
    有参数的程序,可以被调用
    怎样用VB编写.DLL动态链接库文件
    Oracle 存储过程包
    EB(存储单位)
    排序之快速排序(上)
    排序之冒泡排序
    排序之堆排序
  • 原文地址:https://www.cnblogs.com/LoveJenny/p/2041516.html
Copyright © 2011-2022 走看看