重新想象 Windows 8 Store Apps (61) - 通信: http, oauth 原文:重新想象 Windows 8 Store Apps (61) - 通信: http, oauth
[源碼下載]
重新想象 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
<Pagex:Class="XamlDemo.Communication.HTTP.Summary"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:XamlDemo.Communication.HTTP"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><TextBlock Name="lblMsg" FontSize="14.667" /><Button Name="btnPost" Content="http post" Click="btnPost_Click_1" Margin="0 10 0 0" /><Button Name="btnCancel" Content="cancel" Click="btnCancel_Click_1" Margin="0 10 0 0" /></StackPanel></Grid>
</Page> 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<KeyValuePair<
string,
string>>
{new KeyValuePair<
string,
string>(
"param1",
"web"),new KeyValuePair<
string,
string>(
"param2",
"abcd")});// http 請求的數據request.Content =
postData;// http 請求的頭信息request.Headers.Referrer =
new Uri(
"http://webabcd.cnblogs.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<KeyValuePair<
string,
string>>
{new KeyValuePair<
string,
string>(
"param1",
"web"),new KeyValuePair<
string,
string>(
"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[i] = (
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
<Pagex:Class="XamlDemo.Communication.OpenAuth.ClientDemo"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:XamlDemo.Communication.OpenAuth"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><Button Name="btnWeibo" Content="登錄新浪微博,并返回登錄用戶好友最新發布的微博" Click="btnWeibo_Click" /><TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" Margin="0 10 0 0" /></StackPanel></Grid>
</Page> 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.cnblogs.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 codeWebAuthenticationResult 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 codevar 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 tokenHttpClient client =
new HttpClient();var response =
await client.PostAsync(
new Uri(requestAccessToken_url),
null);// 第二步的結果:獲取其中的 access tokenvar 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 沒有提交新浪微博開放平臺審核,所以需要在新浪微博開放平臺中添加測試賬號,否則會出現異常
}}/// <summary>/// 模擬 QueryString 的實現/// </summary>/// <param name="queryString">query 字符串</param>/// <param name="key">key</param>private string QueryString(
string queryString,
string key){return Regex.Match(queryString,
string.Format(
@"(?<=(\&|\?|^)({0})\=).*?(?=\&|$)", key), RegexOptions.IgnoreCase).Value;} }
}/** OAuth 2.0 的 Protocol Flow+--------+ +---------------+| |--(A)- Authorization Request ->| Resource || | | Owner || |<-(B)-- Authorization Grant ---| || | +---------------+| || | +---------------+| |--(C)-- Authorization Grant -->| Authorization || Client | | Server || |<-(D)----- Access Token -------| || | +---------------+| || | +---------------+| |--(E)----- Access Token ------>| Resource || | | Server || |<-(F)--- Protected Resource ---| |+--------+ +---------------+
*/
OK
[源碼下載]
posted on
2014-03-09 15:50 NET未來之路 閱讀(
...) 評論() 編輯 收藏
轉載于:https://www.cnblogs.com/lonelyxmas/p/3590134.html
總結
以上是生活随笔為你收集整理的重新想象 Windows 8 Store Apps (61) - 通信: http, oauth的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。