【Windows 8 Store App】學習三:HTTP

原文 http://www.cnblogs.com/java-koma/archive/2013/05/22/3093309.htmlhtml

1,HttpClientjava

Win 8提供了System.Net.Http.HttpClient類進行經常使用的http網絡請求,HttpClient提供瞭如下構造函數。數組

		// 摘要:
		// 初始化 System.Net.Http.HttpClient 類的新實例。
		public HttpClient();
		//
		// 摘要:
		// 用特定的處理程序初始化 System.Net.Http.HttpClient 類的新實例。
		//
		// 參數:
		// handler:
		// 用於發送請求的使用的 HTTP 處理程序堆棧。
		public HttpClient(HttpMessageHandler handler);
		//
		// 摘要:
		// 用特定的處理程序初始化 System.Net.Http.HttpClient 類的新實例。
		//
		// 參數:
		// handler:
		// System.Net.Http.HttpMessageHandler 負責處理 HTTP 響應消息。
		//
		// disposeHandler:
		// 若是內部處理程序應由 Dispose () 處理,則爲 true;若是您但願重用內部處理程序,則爲 false。
		public HttpClient(HttpMessageHandler handler, bool disposeHandler);

 

第2個構造函數經常使用來處理在請求前添加header(如:Cookie),響應時解析header。 cookie

下面使用HttpClient處理POST/GET提交:網絡

#1. 讓咱們先來定義好key-value類型的參數,用於提交。session

	public class Parameter
	{
		public string key { get; set; }
		public string value { get; set; }

		public Parameter() { }
		public Parameter(string key, string value)
		{
			this.key = key;
			this.value = value;
		}
	}

 

#2. POST/GET:異步

		private static async Task<string> doRequest<T>(string url, List<Parameter> paramList, bool isPost)
		{
			System.Net.Http.HttpClient httpClient = null;
			try
			{
				httpClient = new System.Net.Http.HttpClient();
				httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
				HttpResponseMessage response = null;
				// POST
				if (isPost)
				{
					MultipartFormDataContent form = getPostForm(paramList);
					response = await httpClient.PostAsync(new Uri(url), form);
				}
				// GET
				else
				{
					url = generateGetUrl(url, paramList);
					response = await httpClient.GetAsync(new Uri(url));
				}
				return await response.Content.ReadAsStringAsync();
			}
			catch (Exception) { }
			finally
			{
				if (httpClient != null)
				{
					httpClient.Dispose();
					httpClient = null;
				}
			}
			return null;
		}
		private static string generateGetUrl(string url, List<Parameter> paramList)
		{
			if(paramList == null || paramList.Count <= 0)
			{
				return url;
			}
			StringBuilder sb = new StringBuilder();
			foreach (Parameter item in this.ParamList)
			{
				if (item == null || string.IsNullOrWhiteSpace(item.key) || string.IsNullOrWhiteSpace(item.value))
				{
					continue;
				}
				if (sb.Length > 0)
				{
					sb.Append("&");
				}
				sb.Append(string.Format("{0}={1}", item.key, System.Net.WebUtility.UrlEncode(item.value)));
			}
			return url + (url.IndexOf("?") == -1 ? "?" : "&") + sb.ToString();
		}

		private static MultipartFormDataContent getPostForm(List<Parameter> paramList) 
		{
			MultipartFormDataContent form = new MultipartFormDataContent();
			if (paramList != null)
			{
				foreach (var param in paramList)
				{
					if (!string.IsNullOrWhiteSpace(param.key))
					{
						form.Add(new StringContent(param.value, UTF8Encoding.UTF8), param.key);
					}
				}
			}
			return form;
		}


#3. 處理Cookie,async

一般狀況下咱們須要保持client與server之間的session,server端是經過cookie來識別一個client與另一個client的。ide

咱們使用上面HttpClient的第2個構造函數,經過MessageProcessingHandler和CookieContainer來每次請求前,把cookie添加到request的header中。函數

	public class CookieHandler : MessageProcessingHandler
	{
		static CookieHandler()
        {
            CookieContainer = new CookieContainer();
        }

        public static CookieContainer CookieContainer
        {
            get;
            set;
        }

		public CookieHandler() : base(new CookieHttpClientHandler())
        {
        }

		protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
		{
			return request;
		}

		protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, System.Threading.CancellationToken cancellationToken)
		{
			Uri httpsUri = new Uri("https://" + response.RequestMessage.RequestUri.Host);

			var cookieCollection = CookieContainer.GetCookies(httpsUri);
			foreach (Cookie cookie in cookieCollection)
			{
				cookie.Secure = false;
			}

			return response;
		}
	}

	class CookieHttpClientHandler : HttpClientHandler 
	{
		public CookieHttpClientHandler() 
		{
			CookieContainer = CookieHandler.CookieContainer;
		}
	}


使用方式跟前面POST/GET代碼惟一不一樣的是:在構造HttpClient對象時,傳入CookieHandler:

var httpClient = new System.Net.Http.HttpClient(new CookieHandler());


2, 文件下載

#1 HttpClient提供了字節流的方式來讀取文件,但我測試發現,下載是成功了,但文件常常出現缺乏字節的狀況。不清楚是怎麼回事。

		//
		// 摘要:
		// 將 GET 請求發送到指定 URI 並在異步操做中以字節數組的形式返回響應正文。
		//
		// 參數:
		// requestUri:
		// 請求發送到的 URI。
		//
		// 返回結果:
		// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
		//
		// 異常:
		// System.ArgumentNullException:
		// requestUri 爲 null。
		public Task<byte[]> GetByteArrayAsync(string requestUri);
		//
		// 摘要:
		// 將 GET 請求發送到指定 URI 並在異步操做中以字節數組的形式返回響應正文。
		//
		// 參數:
		// requestUri:
		// 請求發送到的 URI。
		//
		// 返回結果:
		// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
		//
		// 異常:
		// System.ArgumentNullException:
		// requestUri 爲 null。
		public Task<byte[]> GetByteArrayAsync(Uri requestUri);
		//
		// 摘要:
		// 將 GET 請求發送到指定 URI 並在異步操做中以流的形式返回響應正文。
		//
		// 參數:
		// requestUri:
		// 請求發送到的 URI。
		//
		// 返回結果:
		// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
		//
		// 異常:
		// System.ArgumentNullException:
		// requestUri 爲 null。
		public Task<System.IO.Stream> GetStreamAsync(string requestUri);
		//
		// 摘要:
		// 將 GET 請求發送到指定 URI 並在異步操做中以流的形式返回響應正文。
		//
		// 參數:
		// requestUri:
		// 請求發送到的 URI。
		//
		// 返回結果:
		// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
		//
		// 異常:
		// System.ArgumentNullException:
		// requestUri 爲 null。
		public Task<System.IO.Stream> GetStreamAsync(Uri requestUri);

 

#2. BackgroundDownloader

Win 8提供了BackgroundDownloader能夠用於在後臺下載文件,它也能夠調用setRequestHeader向請求中添加header信息 (與上面的CookieHandler結合使用,能夠處理那些須要登錄才能下載文件的狀況),下面演示了普通的文件下載:

		public async static Task<IAsyncOperation<StorageFile>> DownloadAsync(string url)
		{
			string fileName = url.Substring(url.LastIndexOf("/") + 1).Trim();
			var option = Windows.Storage.CreationCollisionOption.ReplaceExisting;
			StorageFile destinationFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, option);
			BackgroundDownloader downloader = new BackgroundDownloader();
			DownloadOperation download = downloader.CreateDownload(new Uri(url), destinationFile);
			await download.StartAsync().AsTask();
			ResponseInformation response = download.GetResponseInformation();
			if(response.StatusCode == 200)
			{
				DownloadHelper.addDownloadFileSuccess(fileName);
				return DownloadHelper.getDownloadFileAsync(fileName);
			}
			return null;
		}
相關文章
相關標籤/搜索