首页 > 代码库 > 重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient

重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient

[源码下载]


重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient



作者:webabcd


介绍
重新想象 Windows 8.1 Store Apps 之通信的新特性

  • 新的 HttpClient
  • http get string
  • http get stream
  • http post string
  • http post stream



示例
HTTP 服务端
WebServer/HttpDemo.aspx.cs

/* * 用于响应 http 请求 */using System;using System.IO;using System.Threading;using System.Web;namespace WebServer{    public partial class HttpDemo : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            // 停 3 秒,以方便测试 http 请求的取消            Thread.Sleep(3000);            var action = Request.QueryString["action"];            switch (action)            {                case "getString": // 响应 http get string                     Response.Write("hello webabcd: " + DateTime.Now.ToString("hh:mm:ss"));                    break;                case "getStream": // 响应 http get stream                     Response.Write("hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd");                    break;                case "postString": // 响应 http post string                     Response.Write(string.Format("param1:{0}, param2:{1}, referrer:{2}", Request.Form["param1"], Request.Form["param2"], Request.UrlReferrer));                    break;                case "postStream": // 响应 http post stream                     using (StreamReader reader = new StreamReader(Request.InputStream))                    {                        if (Request.InputStream.Length > 1024 * 100)                        {                            // 接收的数据太大,则显示“数据接收成功”                            Response.Write("数据接收成功");                        }                        else                        {                            // 显示接收到的数据                            string body = reader.ReadToEnd();                            Response.Write(Server.HtmlEncode(body));                        }                    }                     break;                case "uploadFile": // 处理上传文件的请求                    for (int i = 0; i < Request.Files.Count; i++)                    {                        string key = Request.Files.GetKey(i);                        HttpPostedFile file = Request.Files.Get(key);                        string savePath = @"d:\" + file.FileName;                        // 保存文件                        file.SaveAs(savePath);                        Response.Write(string.Format("key: {0}, fileName: {1}, savePath: {2}", key, file.FileName, savePath));                        Response.Write("\n");                    }                    break;                case "outputCookie": // 用于显示服务端获取到的 cookie 信息                    for (int i = 0; i < Request.Cookies.Count; i++)                    {                        HttpCookie cookie = Request.Cookies[0];                        Response.Write(string.Format("cookieName: {0}, cookieValue: {1}", cookie.Name, cookie.Value));                        Response.Write("\n");                    }                    break;                case "outputCustomHeader": // 用于显示一个自定义的 http header                    Response.Write("myRequestHeader: " + Request.Headers["myRequestHeader"]);                    break;                default:                    break;            }            Response.End();        }    }}


1、演示新的 HttpClient
Summary.xaml.cs

/* * 本例简要说明新的命名空间 Windows.Web.Http 下的新的 HttpClient 的用法(其他相关类也均来自新的 Windows.Web.Http 命名空间) * 通过 HttpClient, HttpRequestMessage, HttpResponseMessage 实现 HTTP 通信 *  *  * 在 win8.1 中增强了 HttpClient 的功能并将此增强版的 HttpClient 转移至了 Windows.Web.Http 命名空间下(原 win8 的 HttpClient 在 System.Net.Http 命名空间下,依旧可用) * 1、如果要查看 System.Net.Http 命名空间下的 HttpClient 的用法请参见:http://www.cnblogs.com/webabcd/archive/2013/09/23/3334233.html * 2、关于支持 OAuth 2.0 验证的客户端也请参见:http://www.cnblogs.com/webabcd/archive/2013/09/23/3334233.html *  *  * HttpClient - 用于发起 http 请求,以及接收 http 响应 *     GetStringAsync(), GetAsync(), GetBufferAsync(), GetInputStreamAsync() - http get 请求 *     DeleteAsync() - http delete 请求 *     PostAsync(), PutAsync() - http post/put 请求 *         参数:IHttpContent content - http 请求的数据 *             实现了 IHttpContent 的类有:HttpStringContent, HttpBufferContent, HttpStreamContent, HttpFormUrlEncodedContent, HttpMultipartFormDataContent 等 *         参数:HttpCompletionOption completionOption(HttpCompletionOption 枚举) *             ResponseContentRead - 获取到全部内容后再返回数据,默认值 *             ResponseHeadersRead - 获取到头信息后就返回数据,用于流式获取 *     SendRequestAsync() - 根据指定的 HttpRequestMessage 对象发起请求 *  * HttpRequestMessage - http 请求 *     Method - http 方法 *     RequestUri - 请求的 uri *     Headers - http 的请求头信息 *     Properties - 当做上下文用 *     Content - http 请求的内容(IHttpContent 类型) *         实现了 IHttpContent 的类有:HttpStringContent, HttpBufferContent, HttpStreamContent, HttpFormUrlEncodedContent, HttpMultipartFormDataContent 等 *     TransportInformation - 获取一个 HttpTransportInformation 类型的对象,用于 https 相关 *          * HttpResponseMessage - http 响应 *     RequestMessage - 对应的 HttpRequestMessage 对象 *     Headers - http 的响应头信息 *     Version - http 版本,默认是 1.1 *     Source - 数据来源(HttpResponseMessageSource 枚举:Cache 或 Network) *     StatusCode - http 响应的状态码 *     ReasonPhrase - http 响应的状态码所对应的短语 *     IsSuccessStatusCode - http 响应的状态码是否是成功的值(200-299) *     EnsureSuccessStatusCode() - 当 IsSuccessStatusCode 为 false 时会抛出异常 *      *  * 另: * win8 metro 的 http 抓包可用 fiddler *  * 还有: * http 通信还可以通过如下方法实现 * HttpWebRequest webRequest = WebRequest.Create(url); */using System;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows.Web.Http;namespace Windows81.Communication.HTTP{    public sealed partial class Summary : Page    {        private HttpClient _httpClient;        private CancellationTokenSource _cts;        public Summary()        {            this.InitializeComponent();        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            // 释放资源            if (_httpClient != null)            {                _httpClient.Dispose();                _httpClient = null;            }            if (_cts != null)            {                _cts.Dispose();                _cts = null;            }        }        private async void btnPost_Click(object sender, RoutedEventArgs e)        {            _httpClient = new HttpClient();            _cts = new CancellationTokenSource();            try            {                string url = "http://localhost:39630/HttpDemo.aspx?action=postString";                // 创建一个 HttpRequestMessage 对象                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(url));                // 需要 post 的数据                HttpFormUrlEncodedContent postData = http://www.mamicode.com/new HttpFormUrlEncodedContent(                    new List<KeyValuePair<string, string>>                    {                        new KeyValuePair<string, string>("param1", "web"),                        new KeyValuePair<string, string>("param2", "abcd")                    }                );                // http 请求的数据                request.Content = postData;                // http 请求的头信息(叽歪一个,终于把 Referrer 改成 Referer 了)                request.Headers.Referer = new Uri("http://webabcd.cnblogs.com");                // 请求 HttpRequestMessage 对象,并返回 HttpResponseMessage 数据                HttpResponseMessage response = await _httpClient.SendRequestAsync(request).AsTask(_cts.Token); // 取消请求的方式改为通过 CancellationTokenSource 来实现了                // http 响应的状态码及其对应的短语                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;                lblMsg.Text += Environment.NewLine;                // 以字符串的方式获取响应数据                lblMsg.Text += await response.Content.ReadAsStringAsync();                lblMsg.Text += Environment.NewLine;            }            catch (TaskCanceledException)            {                lblMsg.Text += "取消了";                lblMsg.Text += Environment.NewLine;            }            catch (Exception ex)            {                lblMsg.Text += ex.ToString();                lblMsg.Text += Environment.NewLine;            }        }        private void btnCancel_Click(object sender, RoutedEventArgs e)        {            // 取消 http 请求            if (_cts != null)            {                _cts.Cancel();                _cts.Dispose();                _cts = null;            }        }    }}


2、演示 http get string
GetString.xaml.cs

/* * 演示 http get string */using System;using System.Threading;using System.Threading.Tasks;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows.Web.Http;namespace Windows81.Communication.HTTP{    public sealed partial class GetString : Page    {        private HttpClient _httpClient;        private CancellationTokenSource _cts;        public GetString()        {            this.InitializeComponent();        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            // 释放资源            if (_httpClient != null)            {                _httpClient.Dispose();                _httpClient = null;            }            if (_cts != null)            {                _cts.Dispose();                _cts = null;            }        }        private async void btnGetString_Click(object sender, RoutedEventArgs e)        {            _httpClient = new HttpClient();            _cts = new CancellationTokenSource();            try            {                HttpResponseMessage response = await _httpClient.GetAsync(new Uri("http://localhost:39630/HttpDemo.aspx?action=getString")).AsTask(_cts.Token); // 取消请求的方式改为通过 CancellationTokenSource 来实现了                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;                lblMsg.Text += Environment.NewLine;                // IHttpContent.ReadAsStringAsync() - 获取 string 类型的响应数据                // IHttpContent.ReadAsBufferAsync() - 获取 IBuffer 类型的响应数据                // IHttpContent.ReadAsInputStreamAsync() - 获取 IInputStream 类型的响应数据                lblMsg.Text += await response.Content.ReadAsStringAsync();                lblMsg.Text += Environment.NewLine;            }            catch (TaskCanceledException)            {                lblMsg.Text += "取消了";                lblMsg.Text += Environment.NewLine;            }            catch (Exception ex)            {                lblMsg.Text += ex.ToString();                lblMsg.Text += Environment.NewLine;            }        }        private void btnCancel_Click(object sender, RoutedEventArgs e)        {            // 取消 http 请求            if (_cts != null)            {                _cts.Cancel();                _cts.Dispose();                _cts = null;            }        }    }}


3、演示 http get stream
GetStream.xaml.cs

/* * 演示 http get stream */using System;using System.IO;using System.Threading;using System.Threading.Tasks;using Windows.Security.Cryptography;using Windows.Storage.Streams;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows.Web.Http;namespace Windows81.Communication.HTTP{    public sealed partial class GetStream : Page    {        private HttpClient _httpClient;        private CancellationTokenSource _cts;        public GetStream()        {            this.InitializeComponent();        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            // 释放资源            if (_httpClient != null)            {                _httpClient.Dispose();                _httpClient = null;            }            if (_cts != null)            {                _cts.Dispose();                _cts = null;            }        }        private async void btnGetStream_Click(object sender, RoutedEventArgs e)        {            _httpClient = new HttpClient();            _cts = new CancellationTokenSource();            try            {                // HttpCompletionOption.ResponseHeadersRead - 获取到头信息后就返回数据,用于流式获取                HttpResponseMessage response = await _httpClient.GetAsync(                    new Uri("http://localhost:39630/HttpDemo.aspx?action=getStream"),                    HttpCompletionOption.ResponseHeadersRead).AsTask(_cts.Token); // 取消请求的方式改为通过 CancellationTokenSource 来实现了                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;                lblMsg.Text += Environment.NewLine;                // IHttpContent.ReadAsStringAsync() - 获取 string 类型的响应数据                // IHttpContent.ReadAsBufferAsync() - 获取 IBuffer 类型的响应数据                // IHttpContent.ReadAsInputStreamAsync() - 获取 IInputStream 类型的响应数据                using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead())                {                    byte[] buffer = new byte[32];                    int read = 0;                    while ((read = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)                    {                        lblMsg.Text += "读取的字节数: " + read.ToString();                        lblMsg.Text += Environment.NewLine;                        IBuffer responseBuffer = CryptographicBuffer.CreateFromByteArray(buffer);                        lblMsg.Text += CryptographicBuffer.EncodeToHexString(responseBuffer);                        lblMsg.Text += Environment.NewLine;                        buffer = new byte[32];                    }                }            }            catch (TaskCanceledException)            {                lblMsg.Text += "取消了";                lblMsg.Text += Environment.NewLine;            }            catch (Exception ex)            {                lblMsg.Text += ex.ToString();                lblMsg.Text += Environment.NewLine;            }        }        private void btnCancel_Click(object sender, RoutedEventArgs e)        {            // 取消 http 请求            if (_cts != null)            {                _cts.Cancel();                _cts.Dispose();                _cts = null;            }        }    }}


4、演示 http post string
PostString.xaml.cs

/* * 演示 http post string */using System;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows.Web.Http;namespace Windows81.Communication.HTTP{    public sealed partial class PostString : Page    {        private HttpClient _httpClient;        private CancellationTokenSource _cts;        public PostString()        {            this.InitializeComponent();        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            // 释放资源            if (_httpClient != null)            {                _httpClient.Dispose();                _httpClient = null;            }            if (_cts != null)            {                _cts.Dispose();                _cts = null;            }        }        private async void btnPostString_Click(object sender, RoutedEventArgs e)        {            _httpClient = new HttpClient();            _cts = new CancellationTokenSource();            try            {                // 需要 post 的数据                var postData = http://www.mamicode.com/new HttpFormUrlEncodedContent(                    new List<KeyValuePair<string, string>>                    {                        new KeyValuePair<string, string>("param1", "web"),                        new KeyValuePair<string, string>("param2", "abcd")                    }                );                HttpResponseMessage response = await _httpClient.PostAsync(                    new Uri("http://localhost:39630/HttpDemo.aspx?action=postString"),                    postData).AsTask(_cts.Token); // 取消请求的方式改为通过 CancellationTokenSource 来实现了                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;                lblMsg.Text += Environment.NewLine;                // HttpContent.ReadAsStringAsync() - 以 string 方式获取响应数据                // HttpContent.ReadAsByteArrayAsync() - 以 byte[] 方式获取响应数据                // HttpContent.ReadAsStreamAsync() - 以 stream 方式获取响应数据                lblMsg.Text += await response.Content.ReadAsStringAsync();                lblMsg.Text += Environment.NewLine;            }            catch (TaskCanceledException)            {                lblMsg.Text += "取消了";                lblMsg.Text += Environment.NewLine;            }            catch (Exception ex)            {                lblMsg.Text += ex.ToString();                lblMsg.Text += Environment.NewLine;            }        }        private void btnCancel_Click(object sender, RoutedEventArgs e)        {            // 取消 http 请求            if (_cts != null)            {                _cts.Cancel();                _cts.Dispose();                _cts = null;            }        }    }}


5、演示 http post stream
PostStream.xaml.cs

/* * 演示 http post stream */using System;using System.IO;using System.Threading;using System.Threading.Tasks;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using Windows.Web.Http;namespace Windows81.Communication.HTTP{    public sealed partial class PostStream : Page    {        private HttpClient _httpClient;        private CancellationTokenSource _cts;        public PostStream()        {            this.InitializeComponent();        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            // 释放资源            if (_httpClient != null)            {                _httpClient.Dispose();                _httpClient = null;            }            if (_cts != null)            {                _cts.Dispose();                _cts = null;            }        }        private async void btnPostStream_Click(object sender, RoutedEventArgs e)        {            _httpClient = new HttpClient();            _cts = new CancellationTokenSource();            try            {                // 需要 post 的 stream 数据                Stream stream = GenerateSampleStream(128);                HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());                HttpResponseMessage response = await _httpClient.PostAsync(                   new Uri("http://localhost:39630/HttpDemo.aspx?action=postStream"),                   streamContent).AsTask(_cts.Token);// 取消请求的方式改为通过 CancellationTokenSource 来实现了                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;                lblMsg.Text += Environment.NewLine;                // IHttpContent.ReadAsStringAsync() - 获取 string 类型的响应数据                // IHttpContent.ReadAsBufferAsync() - 获取 IBuffer 类型的响应数据                // IHttpContent.ReadAsInputStreamAsync() - 获取 IInputStream 类型的响应数据                lblMsg.Text += await response.Content.ReadAsStringAsync();                lblMsg.Text += Environment.NewLine;            }            catch (TaskCanceledException)            {                lblMsg.Text += "取消了";                lblMsg.Text += Environment.NewLine;            }            catch (Exception ex)            {                lblMsg.Text += ex.ToString();                lblMsg.Text += Environment.NewLine;            }        }        // 生成一个指定大小的内存流        private static MemoryStream GenerateSampleStream(int size)        {            byte[] subData = http://www.mamicode.com/new byte[size];            for (int i = 0; i < subData.Length; i++)            {                subData[i] = (byte)(97 + i % 26); // a-z            }            return new MemoryStream(subData);        }        private void btnCancel_Click(object sender, RoutedEventArgs e)        {            // 取消 http 请求            if (_cts != null)            {                _cts.Cancel();                _cts.Dispose();                _cts = null;            }        }    }}



OK
[源码下载]