HttpLib,一個基於C#語言的http協議的開源類庫,讓異步交互處理數據更容易。html
官方下載地址:http://httplib.codeplex.com/web
本文做用演示的例子的源代碼:源代碼下載ajax
一:HttpLib
瀏覽器
HttpLib類庫中包含三個主要類文件:HttpVerb.cs, NamedFileStream.cs, Request.cs,另外有一個輔助類Utils.cs緩存
基於http協議的異步操做是定義在Request.cs中。包括Get,Head,Post,Delete,Put,Patch,Upload等,而NamedFileStream.cs是在上傳文件到服務器時會用到一個容器類,用於描述上傳的文件。Utils.cs則是對於Url參數的處理工具類。服務器
對於HttpLib類庫實現異步操做是基於WebHttpRequest對象的異步委託實現的,具體的實現代碼能夠到官網下載源代碼,本文接下來更可能是演示以及說明HttpLib類庫是怎麼來運做的,不會涉及到底層採用什麼機制或者相關多線程的問題。多線程
二:用於測試的準備工做
app
爲了更好的測試HttpLib異步調用的結果,我首先建立一個Server服務器對象,而且架設在IIS中啓動起來。異步
Server包含兩個通常處理程序一個.aspx頁面,一個HttpHandler.ashx,另外一個是FileHandler.ashx。還有WebForm.aspx頁面。ide
namespace YZR.Server { /// <summary> /// HttpHandler 的摘要說明 /// </summary> public class HttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { string method = context.Request.HttpMethod.ToString(); if (method.ToLower() == "get") { string Name = context.Request["Name"]; if (string.IsNullOrEmpty(Name)) { context.Response.Write("YZR.Get(No Parameters)"); } else { context.Response.Write("YZR.Get(Name:" + Name + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd") + ")"); } } else { string LYF = context.Request["LYF"]; if (string.IsNullOrEmpty(LYF)) { context.Response.Write("YZR.Post(No Parameters)"); } else { context.Response.Write("YZR.Post(你好,大人:" + LYF + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd") + ")"); } } } public bool IsReusable { get { return false; } } } }
namespace YZR.Server { /// <summary> /// FileHandler 的摘要說明 /// </summary> public class FileHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpFileCollection files = HttpContext.Current.Request.Files; if (files.Count > 0) { HttpPostedFile _upfile = files[0]; string fileName = _upfile.FileName;/*獲取文件名: C:\Documents and Settings\Administrator\桌面\123.jpg*/ string suffix = fileName.Substring(fileName.LastIndexOf(".") + 1).ToLower();/*獲取後綴名並轉爲小寫: jpg*/ int bytes = _upfile.ContentLength;//獲取文件的字節大小 if (suffix != "jpg") ResponseWriteEnd(context, "2"); //只能上傳JPG格式圖片 if (bytes > 1024 * 1024) ResponseWriteEnd(context, "3"); //圖片不能大於1M _upfile.SaveAs(HttpContext.Current.Server.MapPath("~/images/logo.jpg"));//保存圖片 context.Response.Write("上傳成功"); } else { context.Response.Write("請選擇上傳文件"); } } private void ResponseWriteEnd(HttpContext context, string msg) { context.Response.Write(msg); context.Response.End(); } public bool IsReusable { get { return false; } } } }
namespace YZR.Server { public partial class WebForm : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string Name = Request["Name"]; if (!String.IsNullOrEmpty(Name)) { Response.Write("Hello " + Name + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd")); } } } } }
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm.aspx.cs" Inherits="YZR.Server.WebForm" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> WebForm </div> </form> </body> </html>
本文接下來都是基於這個Server對象使用HttpLib類庫進行異步調用。
接下來建立兩個客戶端Client對象,YZR.Client這是一個控制檯程序,YZR.JSClient是WebForm程序。在這兩個程序都添加對HttpLib類庫的引用,而且將在這兩個客戶端中測試從服務器異步調用的結果。
三:Get異步
咱們先來看一下控制檯程序(YZR.Client):
namespace YZR.Client { using Redslide.HttpLib; using System.IO; class Program { static void Main(string[] args) { //Get 無參數 //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); }); //Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); }); //Get 帶參數 //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); }); //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); }); //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); }); Console.WriteLine("This another work");
Console.ReadKey(); } static void Func(String result) { String Test = result; Console.WriteLine(result); } } }
運行控制檯以後,當異步訪問ashx文件是將會顯示通常處理程序返回來的結果。
而對於aspx頁面來講則是一整個頁面的html字符串。
在webform程序中,結果也是同樣的,下面咱們將從服務器獲取頁面數據,而後將獲取到的頁面數據輸出在咱們本身定義的Test.aspx頁面中:
namespace YZR.JSClient { using Redslide.HttpLib; public partial class Test : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { Redslide.HttpLib.Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); }); System.Threading.Thread.Sleep(1000); } } void Func(String result) { String Test = result; Response.Write(Test); } } }
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="YZR.JSClient.Test" %>
四:Post異步
Post的書寫方式是類似於Get方式的:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace YZR.Client { using Redslide.HttpLib; using System.IO; class Program { static void Main(string[] args) { //Get 無參數 //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); }); Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); }); //Get 帶參數 //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); }); //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); }); //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); }); //Post 無參數 //Request.Post("http://localhost:9876/HttpHandler.ashx", new { }, action => Func(action)); //Post 帶參數 //Request.Post("http://localhost:9876/WebForm.aspx", new { Name = "LYF" }, result => { Func(result); }); Console.ReadKey(); } static void Func(String result) { String Test = result; Console.WriteLine(result); } } }
五:瀏覽器端的異步Ajax
Js不具備異步功能,但經過瀏覽器Js+Xml能夠實現Ajax技術異步操做:
var AjaxHelp = { GetXhr: function () { //建立異步對象 var xhr= false; var xmlhttpObj = ["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp","Microsoft.XmlHttp"]; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); } else if(window.ActiveXObject){ for(i=0;i<xmlhttpObj.length;i++) { xhr = new ActiveXObject(xmlhttpObj[i]); if(xhr){ break; } } } else{ alert("暫時不能建立XMLHttpRequest對象"); } return xhr ? xhr:false; }, //處理ajax的get請求 ProcessGet: function (url, callback) { this.ProcessAjax("get", url, null, callback); }, ProcessPost: function (url, params, callback) { this.ProcessAjax("post", url, params, callback); }, //統一處理的方法 ProcessAjax: function (method, url, params, callback) { //1.0建立異步對象 var xhr = this.GetXhr(); if (method == "get") { //2.0打開連接 xhr.open("get", url, true); //3.0不使用緩存 xhr.setRequestHeader("if-modified-since", "0"); } else { //2.0打開連接 xhr.open("post", url, true); //3.0將參數放在form data屬性中 xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded"); } //4.0設置回調函數 xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { //獲得從服務器裏獲得的數據 var content = JSON.parse(xhr.responseText);//---->轉成js對象 //調用回調函數(執行本身的業務邏輯) callback(content); } } //5.0發送請求 xhr.send(params); } };
在代碼上,他們的書寫方式我以爲是極爲的類似,並且他們都是進行異步操做。
六:上傳
使用HttpLib類庫還有一個上傳的異步操做,文章一開始說的NamedFileStream就是爲了上傳文件而定義的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace YZR.Client { using Redslide.HttpLib; using System.IO; class Program { static void Main(string[] args) { //Get 無參數 //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); }); Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); }); //Get 帶參數 //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); }); //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); }); //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); }); //Post 無參數 //Request.Post("http://localhost:9876/HttpHandler.ashx", new { }, action => Func(action)); //Post 帶參數 //Request.Post("http://localhost:9876/WebForm.aspx", new { Name = "LYF" }, result => { Func(result); }); //上傳 //NamedFileStream file = new NamedFileStream("file", "1.jpg", "image/jpeg", new FileStream(@"C:\1.jpg", FileMode.Open)); //Request.Upload("http://localhost:9876/FileHandler.ashx", new { }, new[] { new NamedFileStream("file", "1.jpg", "image/jpeg", new FileStream(@"C:\1.jpg", FileMode.Open)) }, action => Func(action)); Console.ReadKey(); } static void Func(String result) { String Test = result; Console.WriteLine(result); } } }
在服務端Server下images文件夾下就會保存從客戶端上傳上來的文件。
總而言之,HttpLib類庫可讓咱們在後臺中更輕鬆的完成異步調用,當你在程序中須要使用異步時,HttpLib也許能幫得上忙。