您的位置:时时app平台注册网站 > 编程知识 > 稳扎稳打Silverlight(21) - 2.0通信之WebRequest和WebRes

稳扎稳打Silverlight(21) - 2.0通信之WebRequest和WebRes

2019-11-21 02:17

 

图片 1<UserControl x:Class="Silverlight20.Communication.WebRequestGet"
图片 2    xmlns="" 
图片 3    xmlns:x=";
图片 4    <StackPanel HorizontalAlignment="Left" Margin="5">
图片 5    
图片 6        <TextBlock x:Name="lblMsg" />
图片 7        
图片 8    </StackPanel>
图片 9</UserControl>
图片 10

如何使用 WebRequest 发送数据


下面代码描述发送数据给服务器的步骤。

using System;

using System.IO;

using System.Net;

using System.Text;

 

namespace Examples.System.Net

{

    public class WebRequestPostExample

    {

        public static void Main ()

        {

            // Create a request using a URL that can receive a post. 

            WebRequest request = WebRequest.Create ("http://www.contoso.com/PostAccepter.aspx ");

            // Set the Method property of the request to POST.

            request.Method = "POST";

            // Create POST data and convert it to a byte array.

            string postData = "This is a test that posts this string to a Web server.";

            byte[] byteArray = Encoding.UTF8.GetBytes (postData);

            // Set the ContentType property of the WebRequest.

            request.ContentType = "application/x-www-form-urlencoded";

            // Set the ContentLength property of the WebRequest.

            request.ContentLength = byteArray.Length;

            // Get the request stream.

            Stream dataStream = request.GetRequestStream ();

            // Write the data to the request stream.

            dataStream.Write (byteArray, 0, byteArray.Length);

            // Close the Stream object.

            dataStream.Close ();

            // Get the response.

            WebResponse response = request.GetResponse ();

            // Display the status.

            Console.WriteLine (((HttpWebResponse)response).StatusDescription);

            // Get the stream containing content returned by the server.

            dataStream = response.GetResponseStream ();

            // Open the stream using a StreamReader for easy access.

            StreamReader reader = new StreamReader (dataStream);

            // Read the content.

            string responseFromServer = reader.ReadToEnd ();

            // Display the content.

            Console.WriteLine (responseFromServer);

            // Clean up the streams.

            reader.Close ();

            dataStream.Close ();

            response.Close ();

        }

    }

}

说明:

  • 用带 URI 参数的 Create 方法 WebRequest 实例。URI 是接收数据的网络资源。如 "WebRequest request = WebRequest.Create("");";
  • 在 WebRequest 设置任何你需要的属性值。例如,若启用验证,设置 Credentials 属性。
  • 指定协议方法,如 HTTP POST 方法。如 "request.Method = "POST";";
  • 设置 ContentLength 属性。如 "request.ContentLength = byteArray.Length;";
  • 设置 ContentType 属性。如 "request.ContentType = "application/x-www-form-urlencoded";";
  • 调用 GetRequestStream 方法获得流。如 "Stream dataStream = request.GetRequestStream ();";
  • 向返回方法的流对象写入数据。如 "dataStream.Write (byteArray, 0, byteArray.Length);";
  • 调用 Stream.Close 方法关闭请求的流。如 "dataStream.Close ();";
  • 调用 GetResponse 向服务器发送请求。该方法返回一个包含服务器响应的对象。返回 WebResponse 对象的类型由 URI 决定。
  • 你可以访问 WebResponse 的属性,或是把 WebResponse 强制类型转换成具体协议类的实例,来读取具体协议的属性。如 "Console.WriteLine (((HttpWebResponse)response).StatusDescription);";

调用 WebResponse 的 GetResponseStream 方法获得包含服务器发送的响应数据。如 "Stream data = response.GetResponseStream();";

  • 从响应读取数据后,必须关闭,用 Stream.Close 方法或 WebResponse.Close 方法。没必要同时调用,但是同时调用也没什么伤害。当关闭响应时,WebResponse.Close 方法会调用 Stream.Close 方法。如 "response.Close();"。

 

很多情况下一般会使用同步方式发出请求,直到响应后再做后续的逻辑处理等,但有时候后续的逻辑处理不依赖于请求的结果或者是可以挂起等到响应后再处理,又或者是为了解决UI“假死”的现象,这时可以使用异步请求

在线DEMO

作出异步请求


System.Net 中的类使用 .NET Framework 标准的异步编程模型来异步访问网络资源。WebRequest 类的 BeginGetResponseEndGetResponse 方法开始和完成网络资源的异步请求。

备注:
在异步回调方法中使用同步调用会导致性能损失。WebRequest 及其派生类作出的 Internet 请求必须使用 Stream.BeginRead 来读取 WebResponse.GetResponseStream 方法返回的流。

下面代码演示如何用 WebRequest 类使用异步调用。示例控制台应用程序,从命令行获得 URI,之后,随着从网络接收到数据,输出数据到终端。

程序定义了它自己使用的两个类:RequestState 类,通过异步调用传递数据;ClientGetAsync 类,实现对一个网络资源的异步请求。

RequestState 类保存请求状态。它包含 WebRequest 和 Stream 实例,包含当前请求的资源和响应的流,以及缓冲区,包含当前从网络资源接收的数据,还有一个 StringBuilder,它包含完整的响应。当 AsyncCallback 方法与 WebRequest.BeginGetResponse 注册时,RequestStateis 作为参数来传递。

ClientGetAsync 类实现对网络资源的异步请求,并向控制台输出响应。它包含的方法和属性如下所示:

  • allDone 属性包含 ManualResetEvent 类的一个实例,指示请求完成的标识。
  • Main() 方法读取命令行,开始对指定网络资源的请求。它创建 WebRequest 对象 wreq 和 RequestState 对象 rs,调用 BeginGetResponse 开始处理请求,之后调用 allDone.WaitOne() 方法,应用程序将退出,直到完成回调。从网络资源读取响应后,Main() 向控制台输出,应用程序结束。
  • showusage() 方法向控制台显示该示例的用法。
  • RespCallBack() 方法实现对网络资源的异步回调方法。它创建包含响应的 WebResponse 实例,获得响应流,并开始从流中异步读取数据。
  • ReadCallBack() 方法实现对读取响应流的异步回调方法。它把从网络资源接收的数据传输到 RequestState 实例的 ResponseData 属性,再开始另一个异步读取,直到没有数据返回为止。一旦读取所有数据,ReadCallBack() 方法会关闭响应流,并调用 allDone.Set() 方法只是整个响应在 ResponseData 里。

备注
严格来说,所有网络流都要关闭。若你不关闭每个请求和响应流,那么应用程序将失去与服务器的连接,就不能处理其他请求。

using System;

using System.Net;

using System.Threading;

using System.Text;

using System.IO;

 

// The RequestState class passes data across async calls.

public class RequestState

{

   const int BufferSize = 1024;

   public StringBuilder RequestData;

   public byte[] BufferRead;

   public WebRequest Request;

   public Stream ResponseStream;

   // Create Decoder for appropriate enconding type.

   public Decoder StreamDecode = Encoding.UTF8.GetDecoder();



   public RequestState()

   {

      BufferRead = new byte[BufferSize];

      RequestData = new StringBuilder(String.Empty);

      Request = null;

      ResponseStream = null;

   }     

}

 

// ClientGetAsync issues the async request.

class ClientGetAsync 

{

   public static ManualResetEvent allDone = new ManualResetEvent(false);

   const int BUFFER_SIZE = 1024;

 

   public static void Main(string[] args) 

   {

      if (args.Length < 1) 

      {

         showusage();

         return;

      }

 

      // Get the URI from the command line.

      Uri httpSite = new Uri(args[0]);

 

      // Create the request object.

      WebRequest wreq = WebRequest.Create(httpSite);



      // Create the state object.

      RequestState rs = new RequestState();

 

      // Put the request into the state object so it can be passed around.

      rs.Request = wreq;

 

      // Issue the async request.

      IAsyncResult r = (IAsyncResult) wreq.BeginGetResponse(

         new AsyncCallback(RespCallback), rs);

 

      // Wait until the ManualResetEvent is set so that the application 

      // does not exit until after the callback is called.

      allDone.WaitOne();

 

      Console.WriteLine(rs.RequestData.ToString());

   }

 

   public static void showusage() {

      Console.WriteLine("Attempts to GET a URL");

      Console.WriteLine("rnUsage:");

      Console.WriteLine("   ClientGetAsync URL");

      Console.WriteLine("   Example:");

      Console.WriteLine("      ClientGetAsync http://www.contoso.com/");

   }

 

   private static void RespCallback(IAsyncResult ar)

   {

      // Get the RequestState object from the async result.

      RequestState rs = (RequestState) ar.AsyncState;

 

      // Get the WebRequest from RequestState.

      WebRequest req = rs.Request;

 

      // Call EndGetResponse, which produces the WebResponse object

      //  that came from the request issued above.

      WebResponse resp = req.EndGetResponse(ar);         

 

      //  Start reading data from the response stream.

      Stream ResponseStream = resp.GetResponseStream();

 

      // Store the response stream in RequestState to read 

      // the stream asynchronously.

      rs.ResponseStream = ResponseStream;

 

      //  Pass rs.BufferRead to BeginRead. Read data into rs.BufferRead

      IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0, 

         BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs); 

   }

 

 

   private static void ReadCallBack(IAsyncResult asyncResult)

   {

      // Get the RequestState object from AsyncResult.

      RequestState rs = (RequestState)asyncResult.AsyncState;

 

      // Retrieve the ResponseStream that was set in RespCallback. 

      Stream responseStream = rs.ResponseStream;

 

      // Read rs.BufferRead to verify that it contains data. 

      int read = responseStream.EndRead( asyncResult );

      if (read > 0)

      {

         // Prepare a Char array buffer for converting to Unicode.

         Char[] charBuffer = new Char[BUFFER_SIZE];



         // Convert byte stream to Char array and then to String.

         // len contains the number of characters converted to Unicode.

      int len = 

         rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0);

 

         String str = new String(charBuffer, 0, len);

 

         // Append the recently read data to the RequestData stringbuilder

         // object contained in RequestState.

         rs.RequestData.Append(

            Encoding.ASCII.GetString(rs.BufferRead, 0, read));         

 

         // Continue reading data until 

         // responseStream.EndRead returns –1.

         IAsyncResult ar = responseStream.BeginRead( 

            rs.BufferRead, 0, BUFFER_SIZE, 

            new AsyncCallback(ReadCallBack), rs);

      }

      else

      {

         if(rs.RequestData.Length>0)

         {

            //  Display data to the console.

            string strContent;                  

            strContent = rs.RequestData.ToString();

         }

         // Close down the response stream.

         responseStream.Close();         

         // Set the ManualResetEvent so the main thread can exit.

         allDone.Set();                           

      }

      return;

   }    

}

当读取完毕后,将读取的数据(lstBuffer)转换成图片,赋值给pictureBox。

作者:webabcd

创建 Internet 请求——Web、File 和 FTP 请求


应用程序通过 WebRequest.Create 方法创建 WebRequest 实例。该方法是静态方法,基于传递的 URI 创建从 WebRequest 派生的类。

NET Framework 提供 HttpWebRequest 类,它派生自 WebRequest,来处理 HTTP 和 HTTPS 请求。在大多数情况下,WebRequest 类提供了你发出请求的所有属性,但是,如果需要的话,你可以把 WebRequest 对象强制类型转换成 HttpWebRequest,以访问请求的 HTTP 属性。类似地,HttpWebResponse 对象来处理 HTTP 和 HTTPS 请求的响应。若访问 HttpWebResponse 对象的属性,需要把 WebResponse 对象强制类型转换成 HttpWebResponse。

.NET Framework 还提供了 FileWebRequest 和 FileWebResponse 类,来处理使用 "file:" 资源的请求。类似地,FtpWebRequest 和 FtpWebResponse 类用户 "ftp:"。

若处理使用应用程序协议的请求,需要实现从 WebRequest 和 WebResponse 派生的特定协议类。

 

每次读一定的字节,填充到指定的容器中(lstBuffer),当数据还没有读取完毕就一直调用responseStream.BeginRead(buffers, 0, 8, ReadCallBack, responseStream);

OK
[源码下载]

本文内容

  • 请求数据——Internet 服务上传和下载数据
  • 创建 Internet 请求——Web、File 和 FTP 请求
  • 请求一个 Web 页面并在流中检索
  • 如何使用 WebRequest 类发送数据
  • 如何检索与 WebRequest 匹配的具体协议的 WebResponse
  • 使用网络流
  • 作出异步请求

 

在具体需要请求服务器的地方创建WebRequest实例,并调用BeginGetResponse方法

示例
1、对指定的URI做GET请求以及接收响应
WebRequestGet.xaml

请求数据——Internet 服务上传和下载数据


开发运行在今天网络的分布式操作环境中的应用程序,需要一个从所有类型的资源检索数据的高效的,易于​​使用的方法。可插拔协议可以让你开发使用单个接口从多个网络协议检索数据的应用程序。

对于简单的请求和响应事务,WebClient 类提供上传和下载数据的最简单方法。WebClient 提供上传和下载文件的方法,发送和接收流,以及向服务器发送数据缓存区,并接收响应。WebClient 使用 WebRequest 和 WebResponse 类对网络资源作出实际的连接,这样可用于任何已注册的可插拔协议。

需要更复杂事务的客户端应用程序应通过 WebRequest 及其派生类从服务器请求数据。WebRequest 封装连接服务器、发送请求和接收响应的细节。WebRequest 类是一个抽象类,定义了一组对所有使用可插入式协议的应用程序可用的属性和方法。WebRequest 的派生类,如 HttpWebRequest的,实现定义在 WebRequest 的属性和方法。

WebRequest 类创建 WebRequest 派生类的特定协议实例,利用传递的 URI 来确定实例的类型。应用程序应该使用哪个 WebRequest 的派生类来处理请求,这是用 WebRequest.RegisterPrefix 方法注册派生类的构造函数。

调用 WebRequest.GetResponse 方法会对网络资源发出请求。GetResponse 方法从 WebRequest 属性构造特定协议的请求,与服务器进行 TCP 或 UDP 套接字连接,并发送请求。对于向服务器发送数据的请求,如 HTTP POST 或 FTP 请求,WebRequest.GetRequestStream 方法提供了一个包含发送数据的网络流。

GetResponse 方法返回一个与 WebRequest 相匹配的特定协议的 WebResponse。

WebResponse 类也是一个抽象类,它定义对所有使用可插入式协议的应用程序的属性和方法。WebResponse 派生类实现其基础协议的属性和方法。例如,HttpWebResponse 类实现对 HTTP 的 WebResponse 类。

服务器返回的数据对应用程序来说是 WebResponse.GetResponseStream 方法以流的方式。你可以使用此流,如下所示。

StreamReader sr =

   new StreamReader(resp.GetResponseStream(), Encoding.ASCII);

 

private void ReadCallBack(IAsyncResult ar)
{
    using (var responseStream = ar.AsyncState as Stream)
    {
        if (responseStream == null) return;
        var read = responseStream.EndRead(ar);
        if (read > 0)
        {
            lstBuffer.AddRange(buffers);
            responseStream.BeginRead(buffers, 0, 8, ReadCallBack, responseStream);
        }
        else
        {
            lstBuffer.AddRange(buffers);
            Stream s = new MemoryStream(lstBuffer.ToArray());
            pictureBox1.Image = Image.FromStream(s);
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            responseStream.Dispose();
        }
    }
}

WebRequestPost.xaml.cs

请求一个 Web 页面并在流中检索


下面代码演示如何请求一个 Web 页面,并在流中检索结果。

WebClient myClient = new WebClient();

Stream response = myClient.OpenRead("http://www.contoso.com/index.htm");

// The stream data is used here.

response.Close();

 

 

[索引页]
[源码下载]

如何使用 WebRequest 类请求数据


下面代码描述从服务器请求资源的步骤。例如,一个 Web 页面或文件。必须用 URI 确定资源。

using System;

using System.IO;

using System.Net;

using System.Text;

 

namespace Examples.System.Net

{

    public class WebRequestGetExample

    {

        public static void Main ()

        {

            // Create a request for the URL. 

            WebRequest request = WebRequest.Create (

              "http://www.contoso.com/default.html");

            // If required by the server, set the credentials.

            request.Credentials = CredentialCache.DefaultCredentials;

            // Get the response.

            WebResponse response = request.GetResponse ();

            // Display the status.

            Console.WriteLine (((HttpWebResponse)response).StatusDescription);

            // Get the stream containing content returned by the server.

            Stream dataStream = response.GetResponseStream ();

            // Open the stream using a StreamReader for easy access.

            StreamReader reader = new StreamReader (dataStream);

            // Read the content.

            string responseFromServer = reader.ReadToEnd ();

            // Display the content.

            Console.WriteLine (responseFromServer);

            // Clean up the streams and the response.

            reader.Close ();

            response.Close ();

        }

    }

}

说明:

  • 用 URI 参数调用 Create 方法创建一个 WebRequest 实例。如,"*WebRequest request = WebRequest.Create(

备注:.NET Framework 提供利用 URI,从 WebRequestWebResponse 继承的具体协议类,URI 以 "http:"、"https:''、"ftp:" 和 "file:" 开头的 URI。若使用其他协议访问资源,必须实现从 WebRequest and WebResponse 类继承的具体协议类。

  • 在 WebRequest 设置任何你需要的属性值。例如,若启用验证,设置 Credentials 属性。如,"request.Credentials = CredentialCache.DefaultCredentials;"。

多数情况下,WebRequest 类足够接收数据。但是,如果你需要设置具体协议的属性,必须把 WebRequest 强制转换成具体协议的类型。例如,若访问 HttpWebRequest 的属性,应该把 WebRequest 强制转换成 HttpWebRequest。如,设置 HTTP 协议的 UserAgent 属性:"((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";";

  • 调用 GetResponse 发送请求给服务器。返回 WebResponse 对象的实际类型由请求的 URI 决定。

接收响应完成后,必须调用 Close 方法。另外,若你从响应对象获得的是流,那么你可以调用 Stream.Close 方法来关闭。若没有关闭,你的应用程序会失去连接,成为不能处理其他请求。

  • 你可以访问 WebResponse 的属性,或是把 WebResponse 强制类型转换成具体协议类的实例,来读取具体协议的属性。例如,若访问 HttpWebResponse 的属性,可以把 WebResponse 强制类型为 HttpWebResponse。如,"Console.WriteLine (((HttpWebResponse)response).StatusDescription);";
  • 调用 WebResponse.GetResponseStream 方法获得服务器响应的流。如 "Stream dataStream = response.GetResponseStream ();";
  • 从响应读取数据后,必须关闭,用 Stream.Close 方法或 WebResponse.Close 方法。没必要同时调用,但是同时调用也没什么伤害。当关闭响应时,WebResponse.Close 方法会调用 Stream.Close 方法。如 "response.Close();"。

 

private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    using (MemoryStream ms = new MemoryStream(e.Result))
    {
        if (pictureBox1 != null) pictureBox1.Image = Image.FromStream(ms);
    }
}

WebRequestGet.xaml.cs

 

如果是使用WebClient的方式代码量就少很多,调用DownloadDataAsync方法发起异步请求,注册事件DownloadDataCompleted,当异步请求完成的时候会触发 Wc_DownloadDataCompleted事件,Wc_DownloadDataCompleted事件中DownloadDataCompletedEventArgs类型的参数e包含一些信息,其中e.Result就是请求响应的结果(byte[]类型)

图片 11using System;
图片 12using System.Collections.Generic;
图片 13using System.Linq;
图片 14using System.Net;
图片 15using System.Windows;
图片 16using System.Windows.Controls;
图片 17using System.Windows.Documents;
图片 18using System.Windows.Input;
图片 19using System.Windows.Media;
图片 20using System.Windows.Media.Animation;
图片 21using System.Windows.Shapes;
图片 22
图片 23using System.Threading;
图片 24using System.IO;
图片 25
图片 26namespace Silverlight20.Communication
图片 27图片 28图片 29{
图片 30    public partial class WebRequestGet : UserControl
图片 31图片 32    图片 33{
图片 34        // 接收 GET 方式数据的 REST 服务
图片 35        string _url = "";
图片 36
图片 37        // 异常信息
图片 38        string _exception = "";
图片 39        
图片 40        // SynchronizationContext - 同步上下文管理类
图片 41        SynchronizationContext _syncContext;
图片 42
图片 43        public WebRequestGet()
图片 44图片 45        图片 46{
图片 47            InitializeComponent();
图片 48
图片 49            Demo();
图片 50        }
图片 51
图片 52        void Demo()
图片 53图片 54        图片 55{
图片 56            // SynchronizationContext.Current - 当前线程的同步上下文
图片 57            _syncContext = SynchronizationContext.Current;
图片 58
图片 59图片 60            /**//*
图片 61             * HttpWebRequest - 对指定的 URI 发出请求
图片 62             *     HttpWebRequest.Create(uri) - 初始化一个 WebRequest
图片 63             *     HttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state) - 开始对指定 URI 资源做异步请求
图片 64             *         AsyncCallback callback - System.AsyncCallback 委托。异步操作完成时调用的回调方法
图片 65             *         Object state - 包含此异步请求的对象。即相应的 HttpWebRequest 对象
图片 66             *     HttpWebRequest.Abort() - 取消该异步请求
图片 67             *     HttpWebRequest.Accept - HTTP 头的 Accept  部分
图片 68             *     HttpWebRequest.ContentType - HTTP 头的 ContentType 部分
图片 69             *     HttpWebRequest.Headers - HTTP 头的 key/value 对集合
图片 70             *     HttpWebRequest.Method - HTTP 方法(只支持GET和POST)
图片 71             *     HttpWebRequest.RequestUri - 所请求的 URI
图片 72             *     HttpWebRequest.HaveResponse - 是否接收到了指定 URI 的响应
图片 73             *     HttpWebRequest.AllowReadStreamBuffering - 是否对从 Internet 资源接收的数据做缓冲处理。默认值为true,将数据缓存在客户端内存中,以便随时被应用程序读取
图片 74             */
图片 75
图片 76            HttpWebRequest request = WebRequest.Create(
图片 77                new Uri(_url, UriKind.Absolute)) as HttpWebRequest;
图片 78            request.Method = "GET";
图片 79            request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
图片 80        }
图片 81
图片 82        private void ResponseCallback(IAsyncResult result)
图片 83图片 84        图片 85{
图片 86            // IAsyncResult.AsyncState - AsyncCallback 传过来的对象
图片 87            HttpWebRequest request = result.AsyncState as HttpWebRequest;
图片 88
图片 89            WebResponse response = null;
图片 90
图片 91            try
图片 92图片 93            图片 94{
图片 95                // HttpWebRequest.EndGetResponse(IAsyncResult) - 结束对指定 URI 资源做异步请求
图片 96                //     返回值为 WebResponse 对象
图片 97                response = request.EndGetResponse(result) as HttpWebResponse;
图片 98            }
图片 99            catch (Exception ex)
图片 100图片 101            图片 102{
图片 103                _exception = ex.ToString();
图片 104            }
图片 105
图片 106            // SynchronizationContext.Post(SendOrPostCallback d, Object state) - 将异步消息发送到该同步上下文中
图片 107            //     SendOrPostCallback d - System.Threading.SendOrPostCallback 委托
图片 108            //     Object state - 需要传递的参数
图片 109            _syncContext.Post(GetResponse, response);
图片 110        }
图片 111
图片 112        private void GetResponse(object state)
图片 113图片 114        图片 115{
图片 116图片 117            /**//*
图片 118             * HttpWebResponse - 对指定的 URI 做出响应
图片 119             *     GetResponseStream() - 获取响应的数据流
图片 120             */
图片 121
图片 122            HttpWebResponse response = state as HttpWebResponse;
图片 123
图片 124            if (response != null)
图片 125图片 126            图片 127{
图片 128                Stream responseStream = response.GetResponseStream();
图片 129                using (StreamReader sr = new StreamReader(responseStream))
图片 130图片 131                图片 132{
图片 133                    lblMsg.Text = sr.ReadToEnd();
图片 134                }
图片 135            }
图片 136            else
图片 137图片 138            图片 139{
图片 140                lblMsg.Text = _exception;
图片 141            }
图片 142        }
图片 143    }
图片 144}
图片 145

如何检索与 WebRequest 匹配的具体协议的 WebResponse


下面演示检索与 WebRequest 匹配的具体协议的 WebResponse。

WebRequest req = WebRequest.Create("http://www.contoso.com/");

WebResponse resp = req.GetResponse();

 

 

图片 146using System;
图片 147using System.Collections.Generic;
图片 148using System.Linq;
图片 149using System.Net;
图片 150using System.Windows;
图片 151using System.Windows.Controls;
图片 152using System.Windows.Documents;
图片 153using System.Windows.Input;
图片 154using System.Windows.Media;
图片 155using System.Windows.Media.Animation;
图片 156using System.Windows.Shapes;
图片 157
图片 158using System.Threading;
图片 159using System.IO;
图片 160
图片 161namespace Silverlight20.Communication
图片 162图片 163图片 164{
图片 165    public partial class WebRequestPost : UserControl
图片 166图片 167    图片 168{
图片 169        // 接收 POST 方式数据的 REST 服务
图片 170        string _url = "";
图片 171
图片 172        // 异常信息
图片 173        string _exception = "";
图片 174
图片 175        // SynchronizationContext - 同步上下文管理类
图片 176        SynchronizationContext _syncContext;
图片 177
图片 178        public WebRequestPost()
图片 179图片 180        图片 181{
图片 182            InitializeComponent();
图片 183
图片 184            Demo();
图片 185        }
图片 186
图片 187        void Demo()
图片 188图片 189        图片 190{
图片 191            _syncContext = SynchronizationContext.Current;
图片 192
图片 193            HttpWebRequest request = WebRequest.Create(
图片 194                new Uri(_url, UriKind.Absolute)) as HttpWebRequest;
图片 195
图片 196            request.Method = "POST";
图片 197
图片 198            // BeginGetRequestStream(AsyncCallback callback, Object state) - 向指定的 URI 资源发送数据的流的异步请求
图片 199            //     AsyncCallback callback - System.AsyncCallback 委托
图片 200            //     Object state - 包含此异步请求的对象。即相应的 HttpWebRequest 对象
图片 201            IAsyncResult asyncResult = request.BeginGetRequestStream(
图片 202                new AsyncCallback(RequestStreamCallback), request);
图片 203        }
图片 204
图片 205        private void RequestStreamCallback(IAsyncResult result)
图片 206图片 207        图片 208{
图片 209            HttpWebRequest request = result.AsyncState as HttpWebRequest;
图片 210            request.ContentType = "application/x-www-form-urlencoded";
图片 211
图片 212            // HttpWebRequest.EndGetRequestStream(IAsyncResult) - 返回用于将数据写入某 URI 资源的 Stream
图片 213            Stream requestStream = request.EndGetRequestStream(result);
图片 214
图片 215            StreamWriter streamWriter = new StreamWriter(requestStream);
图片 216
图片 217            // byte[] postdata = System.Text.Encoding.UTF8.GetBytes("name=webabcd");
图片 218            // 多个参数用“&”分隔
图片 219            streamWriter.Write("name=webabcd");
图片 220
图片 221            streamWriter.Close();
图片 222
图片 223            request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
图片 224        }
图片 225
图片 226        private void ResponseCallback(IAsyncResult result)
图片 227图片 228        图片 229{
图片 230            HttpWebRequest request = result.AsyncState as HttpWebRequest;
图片 231
图片 232            WebResponse response = null;
图片 233
图片 234            try
图片 235图片 236            图片 237{
图片 238                response = request.EndGetResponse(result);
图片 239            }
图片 240            catch (Exception ex)
图片 241图片 242            图片 243{
图片 244                _exception = ex.ToString();
图片 245            }
图片 246
图片 247            // 调用 UI 线程
图片 248            _syncContext.Post(GetResponse, response);
图片 249        }
图片 250
图片 251        private void GetResponse(object state)
图片 252图片 253        图片 254{
图片 255图片 256            /**//*
图片 257             * HttpWebResponse - 对指定的 URI 做出响应
图片 258             *     GetResponseStream() - 获取响应的数据流
图片 259             *     ContentLength - 接收的数据的内容长度
图片 260             *     ContentType - HTTP 头的 ContentType 部分
图片 261             *     Method - HTTP 方法
图片 262             *     ResponseUri - 响应该请求的 URI
图片 263             *     StatusCode - 响应状态 [System.Net.HttpStatusCode枚举]
图片 264             *         HttpStatusCode.OK - HTTP 状态为 200
图片 265             *         HttpStatusCode.NotFound - HTTP 状态为 404
图片 266             *     StatusDescription - 响应状态的说明
图片 267             */
图片 268
图片 269            HttpWebResponse response = state as HttpWebResponse;
图片 270
图片 271            if (response != null && response.StatusCode == HttpStatusCode.OK)
图片 272图片 273            图片 274{
图片 275                Stream responseStream = response.GetResponseStream();
图片 276                using (StreamReader sr = new StreamReader(responseStream))
图片 277图片 278                图片 279{
图片 280                    lblMsg.Text = string.Format("接收的数据的内容长度:{0}rnHTTP 头的 ContentType 部分:{1}rnHTTP 方法:{2}rn响应该请求的 URI:{3}rn响应状态:{4}rn响应状态的说明:{5}rn响应的结果:{6}rn",
图片 281                        response.ContentLength,
图片 282                        response.ContentType,
图片 283                        response.Method,
图片 284                        response.ResponseUri,
图片 285                        response.StatusCode,
图片 286                        response.StatusDescription,
图片 287                        sr.ReadToEnd());
图片 288                }
图片 289            }
图片 290            else
图片 291图片 292            图片 293{
图片 294                lblMsg.Text = _exception;
图片 295            }
图片 296        }
图片 297    }
图片 298}

使用网络流


在 .NET Framework 中,网络资源表示为流。通过看作流,.NET Framework 提供如下功能:

  • 发送和接收 Web 数据的一般方法。无论文件的实际内容是什么——HTML、XML 或其他——你的应用程序可以使用 Stream.Write 和 Stream.Read 发送和接收数据。.
  • 与 .NET Framework 的流兼容。整个 .NET Framework 都使用流,它具有完善的基础结构。例如,你的应用程序,可以把从 FileStream 读取 XML 数据,改成从 NetworkStream 读取数据,仅仅需要改几行代码而已。NetworkStream 和其他流的主要区别是,NetworkStream  是不能寻址(seek)的,CanSeek 属性总是返回 false,并且 SeekPosition 方法会抛出 NotSupportedException 异常。
  • 数据到达时处理。流提供当从网络到达时访问数据,而不用迫使应用程序等到整个数据下载完成。

System.Net.Sockets 命名空间包含一个专门用于网络资源,实现的 Stream 的 NetworkStream 类。System.Net.Sockets 命名空间中的类使用 NetworkStream 类的代表流。

调用 WebRequest.GetRequestStream 方法,利用返回的流,向网络发送数据。WebRequest 将向服务器发送请求头,之后,你可以调用 BeginWrite、EndWrite 或 Write 方法向网络资源发送数据。某些协议,如 HTTP,可能会要求在发送数据前设置特性协议的属性。下面代码演示如何为发送数据设置 HTTP 协议的属性。假设,变量 sendData 包含要发送的数据,sendLength 变量是要发送的数据的字节数。

HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://www.contoso.com/");

request.Method = "POST";

request.ContentLength = sendLength;

try

{

   Stream sendStream = request.GetRequestStream();

   sendStream.Write(sendData,0,sendLength);

   sendStream.Close();

}

catch

{

   // Handle errors . . .

}

调用 WebResponse.GetResponseStream 方法从网络接收数据。可以从返回的流,通过调用 BeginRead, EndRead, or Read 方法从网络资源读取数据。

当在网络资源中使用流时,记住如下几点:

  • CanSeek 属性总是放回 false,因为 NetworkStream 类不能在流中改变位置。Seek 和 Position 方法会抛出 NotSupportedException 异常。
  • 当使用 WebRequest 和 WebResponse,GetResponseStream 创建的流实例是只读的,GetRequestStream 创建的流实例是只写的。
  • 使用 StreamReader 类很容易编码。下面代码使用 StreamReader 从 WebResponse 中读取 ASCII 编码的流。
  • 如果网络资源不可用,那么 GetResponse 的调用会阻塞。可以使用 BeginGetResponseEndGetResponse 的异步请求。
  • 当创建与服务器的连接时,GetRequestStream 的调用会阻塞。可以使用 BeginGetRequestStreamEndGetRequestStream 的异步请求。

    // Create a response object.

    WebResponse response = request.GetResponse();

    // Get a readable stream from the server.

    StreamReader sr =

    new StreamReader(response.GetResponseStream(), Encoding.ASCII);

    // Use the stream. Remember when you are through with the stream to close it.

    sr.Close();

 

下面用一个例子说明,假设需要请求url,该url对应是一张图片,异步获取后展示到PictureBox中(该例子基于winform的一个窗体中)

稳扎稳打Silverlight(21) - 2.0通信之WebRequest和WebResponse, 对指定的URI发出请求以及接收响应

var wc = new WebClient();
wc.DownloadDataAsync(new Uri("http://localhost/1.jpg"));
wc.DownloadDataCompleted  = Wc_DownloadDataCompleted;

2、对指定的URI做POST请求以及接收响应
WebRequestPost.xaml

 

图片 299<UserControl x:Class="Silverlight20.Communication.WebRequestPost"
图片 300    xmlns="" 
图片 301    xmlns:x=";
图片 302    <StackPanel HorizontalAlignment="Left" Margin="5">
图片 303    
图片 304        <TextBlock x:Name="lblMsg" />
图片 305    
图片 306    </StackPanel>
图片 307</UserControl>
图片 308

string url = "http://localhost/1.jpg";
var request = WebRequest.Create(url);
request.BeginGetResponse(RespCallBack, request);

RespCallBack方法如下,此处ar.AsyncState也就是上面调用BeginGetResponse方法中参数state对应的信息,也就是request

private void RespCallBack(IAsyncResult ar)
{
    var request = ar.AsyncState as WebRequest;
    var response = request?.EndGetResponse(ar);
    Stream responseStream = response?.GetResponseStream();
    responseStream?.BeginRead(buffers, 0, 8, ReadCallBack, responseStream);
}

介绍
Silverlight 2.0 详解WebRequest和WebResponse,对指定的URI做GET和POST请求,以及接收其响应
    HttpWebRequest - 对指定的 URI 发出请求
        Create() - 初始化一个 WebRequest
        BeginGetResponse() - 开始对指定 URI 资源做异步请求
        EndGetResponse() - 结束对指定 URI 资源做异步请求
    HttpWebResponse - 对指定的 URI 做出响应
        GetResponseStream() - 获取响应的数据流

winform中定义了存放数据的变量

由于是异步,此处读数据也是异步读取,ReadCallBack如下:

List<byte> lstBuffer = new List<byte>();
byte[] buffers = new byte[8];

使用WebRequest实例中的BeginGetResponse方法异步获取响应结果,其中参数callback是委托类型,state是自定义的对象,state用于保存一些信息,在callback对应的方法中可能需要用到这些信息。

本文由时时app平台注册网站发布于编程知识,转载请注明出处:稳扎稳打Silverlight(21) - 2.0通信之WebRequest和WebRes

关键词: