设为首页 收藏本站
查看: 1284|回复: 0

重新想象 Windows 8 Store Apps (61)

[复制链接]

尚未签到

发表于 2015-5-22 06:02:25 | 显示全部楼层 |阅读模式
  [源码下载]




重新想象 Windows 8 Store Apps (61) - 通信: http, oauth  
作者:webabcd

介绍
重新想象 Windows 8 Store Apps 之 通信


  • HttpClient 概述
  • http get string
  • http get stream
  • http post string
  • http post stream
  • OAuth 2.0 验证的客户端
  
示例
用于演示 http 通信的服务端
WebServer/HttpDemo.aspx.cs



/*
* 用于响应 http 请求
*/
using System;
using System.IO;
using System.Threading;
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");
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))
{
string body = reader.ReadToEnd();
Response.Write(Server.HtmlEncode(body));
}
break;
default:
break;
}
Response.End();
}
}
}
  
  1、通过 HttpClient, HttpRequestMessage, HttpResponseMessage 实现 HTTP 通信
Communication/HTTP/Summary.xaml













  Communication/HTTP/Summary.xaml.cs



/*
* 通过 HttpClient, HttpRequestMessage, HttpResponseMessage 实现 HTTP 通信
*
* HttpClient - 用于发起 http 请求,以及接收 http 响应
*     BaseAddress - 发送请求的 uri
*     DefaultRequestHeaders - 默认的 http 请求头信息
*     MaxResponseContentBufferSize - 读取响应内容时,所可以缓冲的最大字节数。默认值:64K
*     Timeout - http 请求的超时时间
*     CancelPendingRequests() - 取消该 HttpClient 对象所有挂起的 http 请求
*     GetStringAsync(), GetStreamAsync(), GetByteArrayAsync(), GetAsync() - http get 数据
*     PostAsync(), DeleteAsync(), PutAsync() - http post delete put 数据
*         参数:HttpContent content - http 请求的数据(HttpContent 类型)
*             继承自 HttpContent 的类有:StringContent, ByteArrayContent, StreamContent, FormUrlEncodedContent 等
*         参数:HttpCompletionOption completionOption(HttpCompletionOption 枚举)
*             ResponseContentRead - 获取到全部内容后再返回数据,默认值
*             ResponseHeadersRead - 获取到头信息后就返回数据,用于流式获取
*
* HttpRequestMessage - http 请求
*     Method - http 方法
*     RequestUri - 请求的 uri
*     Version - http 版本,默认是 1.1
*     Headers - http 的请求头信息
*     Content - http 请求的内容(HttpContent 类型)
*         继承自 HttpContent 的类有:StringContent, ByteArrayContent, StreamContent, FormUrlEncodedContent 等
*         
* HttpResponseMessage - http 响应
*     RequestMessage - 对应的 HttpRequestMessage 对象
*     Headers - http 的响应头信息
*     Version - http 版本,默认是 1.1
*     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.Net.Http;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Communication.HTTP
{
public sealed partial class Summary : Page
{
private HttpClient _httpClient;
public Summary()
{
this.InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 释放资源
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
private async void btnPost_Click_1(object sender, RoutedEventArgs e)
{
_httpClient = new HttpClient();
try
{
string url = "http://localhost:39629/HttpDemo.aspx?action=postString";
// 创建一个 HttpRequestMessage 对象
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
// 需要 post 的数据
var postData = new FormUrlEncodedContent(
new List
{
new KeyValuePair("param1", "web"),
new KeyValuePair("param2", "abcd")
}
);
// http 请求的数据
request.Content = postData;
// http 请求的头信息
request.Headers.Referrer = new Uri("http://webabcd.iyunv.com");
// 请求 HttpRequestMessage 对象,并返回 HttpResponseMessage 数据
HttpResponseMessage response = await _httpClient.SendAsync(request);
// 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_1(object sender, RoutedEventArgs e)
{
// 取消 http 请求
            _httpClient.CancelPendingRequests();
}
}
}
  
2、演示 http get string
Communication/HTTP/GetString.xaml.cs



/*
* 演示 http get string
*/
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Communication.HTTP
{
public sealed partial class GetString : Page
{
private HttpClient _httpClient;
public GetString()
{
this.InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 释放资源
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
private async void btnGetString_Click_1(object sender, RoutedEventArgs e)
{
_httpClient = new HttpClient();
try
{
HttpResponseMessage response = await _httpClient.GetAsync(new Uri("http://localhost:39629/HttpDemo.aspx?action=getString"));
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_1(object sender, RoutedEventArgs e)
{
// 取消 http 请求
            _httpClient.CancelPendingRequests();
}
}
}
  
3、演示 http get stream
Communication/HTTP/GetStream.xaml.cs



/*
* 演示 http get stream
*/
using System;
using System.IO;
using System.Net.Http;
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;
namespace XamlDemo.Communication.HTTP
{
public sealed partial class GetStream : Page
{
private HttpClient _httpClient;
public GetStream()
{
this.InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 释放资源
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
private async void btnGetStream_Click_1(object sender, RoutedEventArgs e)
{
_httpClient = new HttpClient();
try
{
// HttpCompletionOption.ResponseHeadersRead - 获取到头信息后就返回数据,用于流式获取
HttpResponseMessage response = await _httpClient.GetAsync(
new Uri("http://localhost:39629/HttpDemo.aspx?action=getStream"),
HttpCompletionOption.ResponseHeadersRead);
lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
lblMsg.Text += Environment.NewLine;
// HttpContent.ReadAsStringAsync() - 以 string 方式获取响应数据
// HttpContent.ReadAsByteArrayAsync() - 以 byte[] 方式获取响应数据
// HttpContent.ReadAsStreamAsync() - 以 stream 方式获取响应数据
using (Stream responseStream = await response.Content.ReadAsStreamAsync())
{
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_1(object sender, RoutedEventArgs e)
{
// 取消 http 请求
            _httpClient.CancelPendingRequests();
}
}
}
  
4、演示 http post string
Communication/HTTP/PostString.xaml.cs



/*
* 演示 http post string
*/
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Communication.HTTP
{
public sealed partial class PostString : Page
{
private HttpClient _httpClient;
public PostString()
{
this.InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 释放资源
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
private async void btnPostString_Click_1(object sender, RoutedEventArgs e)
{
_httpClient = new HttpClient();
try
{
// 需要 post 的数据
var postData = new FormUrlEncodedContent(
new List
{
new KeyValuePair("param1", "web"),
new KeyValuePair("param2", "abcd")
}
);
HttpResponseMessage response = await _httpClient.PostAsync(
new Uri("http://localhost:39629/HttpDemo.aspx?action=postString"),
postData);
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_1(object sender, RoutedEventArgs e)
{
// 取消 http 请求
            _httpClient.CancelPendingRequests();
}
}
}
  
5、演示 http post stream
Communication/HTTP/PostStream.xaml.cs



/*
* 演示 http post stream
*/
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace XamlDemo.Communication.HTTP
{
public sealed partial class PostStream : Page
{
private HttpClient _httpClient;
public PostStream()
{
this.InitializeComponent();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// 释放资源
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
}
}
private async void btnPostStream_Click_1(object sender, RoutedEventArgs e)
{
_httpClient = new HttpClient();
try
{
// 需要 post 的 stream 数据
Stream stream = GenerateSampleStream(128);
StreamContent streamContent = new StreamContent(stream);
HttpResponseMessage response = await _httpClient.PostAsync(
new Uri("http://localhost:39629/HttpDemo.aspx?action=postStream"),
streamContent);
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 static MemoryStream GenerateSampleStream(int size)
{
byte[] subData = new byte[size];
for (int i = 0; i < subData.Length; i++)
{
subData = (byte)(97 + i % 26); // a-z
            }
return new MemoryStream(subData);
}
private void btnCancel_Click_1(object sender, RoutedEventArgs e)
{
// 取消 http 请求
            _httpClient.CancelPendingRequests();
}
}
}
  
6、演示如何开发一个基于 OAuth 2.0 验证的客户端
Communication/OpenAuth/ClientDemo.xaml











  Communication/OpenAuth/ClientDemo.xaml.cs



/*
* 演示如何开发一个基于 OAuth 2.0 验证的客户端
*
* WebAuthenticationBroker - 用于 OAuth 2.0 验证的第一步,可以将第三方 UI 无缝整合进 app
*     AuthenticateAsync(WebAuthenticationOptions options, Uri requestUri, Uri callbackUri) - 请求 authorization code,返回一个 WebAuthenticationResult 类型的数据
*
* WebAuthenticationResult - 请求 authorization code(OAuth 2.0 验证的第一步)的结果
*     ResponseData - 响应的数据         
*     ResponseStatus - 响应的状态
*     
*
* 关于 OAuth 2.0 协议参见:http://tools.ietf.org/html/draft-ietf-oauth-v2-20
*/
using System;
using System.Net.Http;
using System.Text.RegularExpressions;
using Windows.Data.Json;
using Windows.Security.Authentication.Web;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Communication.OpenAuth
{
public sealed partial class ClientDemo : Page
{
public ClientDemo()
{
this.InitializeComponent();
}
private async void btnWeibo_Click(object sender, RoutedEventArgs e)
{
try
{
var appKey = "39261162";
var appSecret = "652ec0b02f814d514fc288f3eab2efda";
var callbackUrl = "http://webabcd.iyunv.com"; // 在新浪微博开放平台设置的回调页
var requestAuthorizationCode_url =
string.Format("https://api.weibo.com/oauth2/authorize?client_id={0}&response_type=code&redirect_uri={1}",
appKey,
callbackUrl);
// 第一步:request authorization code
WebAuthenticationResult WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None,
new Uri(requestAuthorizationCode_url),
new Uri(callbackUrl));
// 第一步的结果
lblMsg.Text = WebAuthenticationResult.ResponseStatus.ToString() + Environment.NewLine;
if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
{
// 从第一步返回的数据中获取 authorization code
var authorizationCode = QueryString(WebAuthenticationResult.ResponseData, "code");
lblMsg.Text += "authorizationCode: " + authorizationCode + Environment.NewLine;
var requestAccessToken_url =
string.Format("https://api.weibo.com/oauth2/access_token?client_id={0}&client_secret={1}&grant_type=authorization_code&redirect_uri={2}&code={3}",
appKey,
appSecret,
callbackUrl,
authorizationCode);
// 第二步:request access token
HttpClient client = new HttpClient();
var response = await client.PostAsync(new Uri(requestAccessToken_url), null);
// 第二步的结果:获取其中的 access token
var jsonString = await response.Content.ReadAsStringAsync();
JsonObject jsonObject = JsonObject.Parse(jsonString);
var accessToken = jsonObject["access_token"].GetString();
lblMsg.Text += "accessToken: " + accessToken + Environment.NewLine;
var requestProtectedResource_url =
string.Format("https://api.weibo.com/2/statuses/friends_timeline.json?access_token={0}",
accessToken);
// 第三步:request protected resource,获取需要的数据(本例为获取登录用户好友最新发布的微博)
var result = await client.GetStringAsync(new Uri(requestProtectedResource_url));
lblMsg.Text += "result: " + result;
}
}
catch (Exception ex)
{
lblMsg.Text += Environment.NewLine;
lblMsg.Text += ex.ToString();
// 由于本 app 没有提交新浪微博开放平台审核,所以需要在新浪微博开放平台中添加测试账号,否则会出现异常
            }
}
///
/// 模拟 QueryString 的实现
///
/// query 字符串
/// key
private string QueryString(string queryString, string key)
{
return Regex.Match(queryString, string.Format(@"(?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-69299-1-1.html 上篇帖子: 重新想象 Windows 8 Store Apps (63) 下篇帖子: 重新想象 Windows 8 Store Apps (3)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表