[源码下载]

重新想象 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(); 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 > * )
{
// 接收的数据太大,则显示“数据接收成功”
Response.Write("数据接收成功");
}
else
{
// 显示接收到的数据
string body = reader.ReadToEnd();
Response.Write(Server.HtmlEncode(body));
}
}
break;
case "uploadFile": // 处理上传文件的请求
for (int i = ; 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 = ; i < Request.Cookies.Count; i++)
{
HttpCookie cookie = Request.Cookies[];
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 = 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[];
int read = ; while ((read = await responseStream.ReadAsync(buffer, , buffer.Length)) > )
{
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[];
}
}
}
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 = 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();
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 = new byte[size];
for (int i = ; i < subData.Length; i++)
{
subData[i] = (byte)( + i % ); // 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
[源码下载]

重新想象 Windows 8.1 Store Apps (88) - 通信的新特性: 新的 HttpClient的更多相关文章

  1. 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件

    [源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  2. 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他

    [源码下载] 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cooki ...

  3. 重新想象 Windows 8.1 Store Apps 系列文章索引

    [源码下载] [重新想象 Windows 8 Store Apps 系列文章] 重新想象 Windows 8.1 Store Apps 系列文章索引 作者:webabcd 1.重新想象 Windows ...

  4. 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

    [源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...

  5. 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar

    [源码下载] 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  6. 重新想象 Windows 8.1 Store Apps (73) - 新增控件: DatePicker, TimePicker

    [源码下载] 重新想象 Windows 8.1 Store Apps (73) - 新增控件: DatePicker, TimePicker 作者:webabcd 介绍重新想象 Windows 8.1 ...

  7. 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout

    [源码下载] 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout 作者:webabcd 介绍重新想象 ...

  8. 重新想象 Windows 8.1 Store Apps (75) - 新增控件: Hub, Hyperlink

    [源码下载] 重新想象 Windows 8.1 Store Apps (75) - 新增控件: Hub, Hyperlink 作者:webabcd 介绍重新想象 Windows 8.1 Store A ...

  9. 重新想象 Windows 8.1 Store Apps (76) - 新增控件: SearchBox

    [源码下载] 重新想象 Windows 8.1 Store Apps (76) - 新增控件: SearchBox 作者:webabcd 介绍重新想象 Windows 8.1 Store Apps 之 ...

随机推荐

  1. 804 pretest 解题

    Answers with Explanations 1. c) s1 and s2 not equal s1 and s3 equal JVM sets a constant pool in whic ...

  2. [AX 2012] Woker user request

    在HR模块和System administrator模块下都能找到Woker user request这个功能,它的作用是为员工创建一个AX账号.比如我们创建一个这样的user request: 注意 ...

  3. 大型网站系统架构演化之路【mark】

    前言 一 个成熟的大型网站(如淘宝.天猫.腾讯等)的系统架构并不是一开始设计时就具备完整的高性能.高可用.高伸缩等特性的,它是随着用户量的增加,业务功能的 扩展逐渐演变完善的,在这个过程中,开发模式. ...

  4. 使用hexo在github上写blog

    使用hexo在github上写blog 安装nodejs http://nodejs.org/ 安装hexo npm install -g hexo 创建bolg文件夹 安装完成后在自己的工作目录创建 ...

  5. 分布式并行数据库将在OLTP 领域促进去“Oracle”

    原文链接:http://www.csdn.net/article/2015-09-11/2825678 摘要:本文全面介绍了分布式数据库和它的设计理念,以及分布式数据库的优势和应用场景,从而引出OLT ...

  6. boost 1.56.0 编译及使用

    boost的编译和使用,经过搜集资料和总结,记录成文.感谢文后所列参考资料的作者. 1 下载 地址:http://sourceforge.net/projects/boost/files/boost/ ...

  7. 查询反模式 - GroupBy、HAVING的理解

    为了最简单地说明问题,我特地设计了一张这样的表. 一.GROUP BY单值规则 规则1:单值规则,跟在SELECT后面的列表,对于每个分组来说,必须返回且仅仅返回一个值. 典型的表现就是跟在SELEC ...

  8. ExtJS远程数据-本地分页

    背景 一般情况下,分页展示是前端只负责展示,后台通过SQL语句实现分页查询.当总数据量在千条以下,适合一次性查询出符合条件的所有数据,让前端页面负责分页也是一种选择. 实例 现通过ExtJS 4扩展类 ...

  9. Swift 函数

    1: 函数形式: Swift函数以关键字func 标示.返回类型->后写明.如果没有返回类型可以省去.多个参数用,分割.其中参数名字在前:类型描述 func GetName(strName:St ...

  10. 向上下左右不间断无缝滚动图片的效果(兼容火狐和IE)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...