HttpContext概念講解

一:HttpContext理論知識:javascript

1:HttpContext類它對Request、Respose、Server等等都進行了封裝,並保證在整個請求週期內均可以隨時隨地的調用;爲繼承 IHttpModule 和 IHttpHandler 接口的類提供了對當前 HTTP 請求的 HttpContext 對象的引用。該對象提供對請求的內部Request、Response 和 Server 屬性的訪問。HttpContext的命名空間:System.Web(在 system.web.dll 中);除了對幾個對象進行封裝外它還有個HttpContext.Item,經過它你能夠在HttpContext的生存週期內提早存儲一些臨時的數據,方便隨時使用。html

2:生存週期:從客戶端用戶點擊併產生了一個向服務器發送請求開始---服務器處理完請求並生成返回到客戶端爲止。針對每一個不一樣用戶的請求,服務器都會建立一個新的HttpContext實例直到請求結束,服務器銷燬這個實例。java

3:當咱們建立一個通常處理程序Handler.ashx時,咱們能夠在文件中看到這一句  public void ProcessRequest (HttpContext context);jquery

4:能夠經過HttpContext.Current得到當前的上下文httpContext的內容;這樣能夠在多處方便獲取咱們想要的數據;web

二:HttpContext.Item的運用瀏覽器

在文中第一點咱們有提到HttpContext.Item能夠經過它來存儲一些臨時的數據;咱們將經過一個實例來演示它的實現,以及在此過程當中應該注意什麼;還針對ASP.NET常見的兩種跳轉進行比較(分別爲:Server.Transfer和Response.Redirect);安全

1:首先咱們新建一個頁面對HttpContext.Item它進行寫入數據(此處不同的是當寫完值後不一樣的頁面跳轉方式):服務器

 
    protected void Btn_Transfer_Click(object sender, EventArgs e)
    {
        List<String> list = new List<string>();
        list.Add("踏浪帥");
        list.Add("www.cnblogs.com/wujy");
        HttpContext.Current.Items["TransferName"] = list;
        Server.Transfer("Index.aspx");
    }
    protected void Btn_Redirect_Click(object sender, EventArgs e)
    {
        List<String> list = new List<string>();
        list.Add("踏浪帥");
        list.Add("www.cnblogs.com/wujy");
        HttpContext.Current.Items["RedirectName"] = list;
        Response.Redirect("Index.aspx");
    }
 

接着咱們再新建一個Index.aspx頁面接收此頁面的值:cookie

 
public partial class Index : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            List<string> list = HttpContext.Current.Items["TransferName"] as List<string>;
            if (list != null)
            {
                foreach (string item in list)
                {
                    Response.Write(string.Format("Transfer輸出的值爲:{0} <br/>", item));
                }
            }

            List<string> ResList = HttpContext.Current.Items["RedirectName"] as List<string>;
            if (ResList != null)
            {
                foreach (string item in ResList)
                {
                    Response.Write(string.Format("Redirect輸出的值爲:{0}", item));
                }
            }
            else
            {
                Response.Write("Response.Redirect傳過來爲空!");
            }
        }
    }
}
 

如今咱們看一下運行的效果:網絡

Server.Transfer方式 Response.Redirect方式

 

從上面運行的結果咱們否則發現使用Server.Transfer方式咱們在接收頁面成功得到咱們寫入的數據;而Response.Redirect方式卻致使數據的丟失;出現這個問題的緣由是Server.Transfer是在服務器直接操做的的和調用的地方屬於同一次http請求,此處若是使用Response.Redirect是從客戶端從新發起了一次Http請求;而正如咱們前面所說的HttpContext的生存週期只能在一個http請求才不會被服務器銷燬這個實例;

針對上面Server.Transfer是在服務器直接操做和調用的咱們其實能夠看一下咱們跳轉時URL地址的變化就知道了,URL它是沒有變化的;

Server.Transfer  

 

而Response.Redirect跳轉後的URL地址是發生變化(它是從客戶端再去作起一次請求訪問到index.aspx頁面):

 

注意:通常的狀況下儘量用Server.Transfer方法(前提是服務器是IIS),Server.Transfer方法更快速,並且由於只在服務器上執行,因此能夠和任何瀏覽器兼容。

Response.Redirect其實上是當服務器碰到這條語句時發送一條指令(包含新的地址)給瀏覽器,而後讓瀏覽器去發送http請求,請求Response.Redirect後面的那個新的http地址,流程以下:瀏覽器文件請求->服務器執行->遇到response.redirect語句->服務器發送Server.Transfer後面的地址給客戶機端的瀏覽器->瀏覽器請求執行新的地址(服務器返回的Response.Redirect後面的地址)這就是一個小小的Response.Redirect的所有過程,
Server.Transfer語句當接受地址後是直接轉向後面的地址,流程以下:瀏覽器文件請求->服務器執行->遇到Server.Transfer語句->服務器轉向新的文件。

 

2:截獲Http請求並做特殊處理

主要是用在Application_BeginRequest方法裏。Application_BeginRequest方法在global.asax.cs裏定義。你能夠在Http請求剛剛開始的時候,截獲他,作一些特殊的處理。這裏你不能用Session來作,由於此時Session對象尚未被創建。 利用Context.Item集合,你能夠在Http請求的整個生命期,經過HttpModules, HttpHandlers, Webforms, and Application 事件。

三:HttpContet對象之Request

1:Request理論知識:

ASP.NET Request 封裝了客戶端請求信息,是從客戶端獲得數據(從瀏覽器獲取數據);經常使用的三種取得數據的方法是:Request.Form、Request.QueryString、Request其第三種是前兩種的一個縮寫,能夠取代前兩種狀況。而前兩種主要對應的Form提交時的兩種不一樣的提交方法:分別是Post方法和Get方法。

 

2:新建一個頁面用來顯示Requesst一些常見屬性信息的內容;

 
public partial class RequestPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            StringBuilder strBuider = new StringBuilder();
            strBuider.Append("客戶端主機的IP地址:" + HttpContext.Current.Request.UserHostAddress + "</br>");
            strBuider.Append("客戶端瀏覽器版本:" + Request.UserAgent + "</br>");
            strBuider.Append("當前由哪一個頁面URL跳轉過來:" + Request.UrlReferrer+ "</br>");
            strBuider.Append("當前要求的URL:" + Request.Url + "</br>");
            strBuider.Append("當前要求的URL絕對地址:" + Request.Url.AbsolutePath + "</br>");
            strBuider.Append("當前要求的URL絕對URI:" + Request.Url.AbsoluteUri + "</br>");
            strBuider.Append("當前要求的URL主機名跟端口:" + Request.Url.Authority + "</br>");
            strBuider.Append("當前要求的URL實例主機的一部分:" + Request.Url.Host + "</br>");
            strBuider.Append("當前要求的URL端口:" + Request.Url.Port + "</br>");
            strBuider.Append("當前要求的URL的內容第一個段:" + Request.Url.Segments[0] + "</br>");
            strBuider.Append("當前要求的URL的內容第二個段:" + Request.Url.Segments[1] + "</br>");
            strBuider.Append("當前要求的URL的內容第三個段:" + Request.Url.Segments[2] + "</br>");
            strBuider.Append("瀏覽器地址欄後的參數"+Request.QueryString + "</br>");
            strBuider.Append("當前網頁在服務器端的實際路徑:" + Request.PhysicalPath + "</br>");
            strBuider.Append("當前文件的物理地址:" + Request.PhysicalApplicationPath + "</br>");
            strBuider.Append("當前網頁的相對地址:" + Request.Path + "<br/>");
            strBuider.Append("當前頁面的URL:" + Request.RawUrl + "<br/>");
            strBuider.Append("客戶端上傳的文件(個數):" + Request.Files.Count + "<br/>");
            strBuider.Append("當前執行網頁的相對地址:" + Request.FilePath + "<br/>");
            strBuider.Append("客戶端瀏覽器的信息:" + Request.Browser + "<br/>");
            strBuider.Append("當前運行程序的服務器端虛擬目錄:" + Request.ApplicationPath + "<br/>");
            strBuider.Append("客戶端瀏覽器的字符設置:" + Request.ContentEncoding + "<br/>");
            Response.Write(strBuider.ToString());
        }
    }
}
 

運行結果顯示(得到客戶端瀏覽器以及一些相關的信息):


 

3:針對表單的提交方式如上面所說的有兩種方式(POST以及GET);接下來咱們則經過幾段代碼來演示有關表單提交的兩種方式以及一些應該注意的事項;

(1)表單Get方式提交:

 相信在咱們日常的開發過程當中使用Get方式進行提交的表單是最常常碰到的,它也是最簡單的一種方式,主要注意在使用Get提交時URL對數據的大小是有限止;還常常碰到的狀況是對URL傳參時一些特殊符號的處理問題;接下來咱們將經過小實例來演示兩種對URL傳參處理特殊符號方式;

首先是使用ASP.NET代碼的Server對象對要傳參進行一個編碼的處理(Server.UrlEncode(string s));

        string UserName = "踏浪帥¥%—*@";
        Server.Transfer("GetPageResult.aspx?UserName="+Server.UrlEncode(UserName)+"&UserID=001");

接上時再對收到的參數進行一個解碼(Get方式使用Request.QueryString[Name]和Request[Name]進行接收參數;解碼Server.UrlDecode(string s)):

            string UserName = Request.QueryString["UserName"];
            Response.Write("第一個傳參值:" + Server.UrlDecode(UserName) + "</br>");

            string UserID = Request["UserID"];
            Response.Write("第二個傳參值:" + UserID + "</br>");

查後運行結果:

另一種方式是使用JS進行傳參,此得使用到的JS中的escape();而它接收解碼跟上面使用ASP.NET代碼是同樣;

 
<head runat="server">
    <title></title>
    <script type="text/javascript" src="jquery-1.4.2.min.js"></script>
    <script language="javascript" type="text/javascript">
        $(function () {
            $("#Btn_Get").bind('click',GetResult);
        })
        function GetResult() {
            var UserName = "踏浪帥¥%—*@";
            location.href = "GetPageResult.aspx?UserID=002&UserName="+escape(UserName);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <input id="Btn_Get" type="button" value="HTML中的JS傳值" />
    </form>
</body>
</html>
 

運行結果:

 

(2)Post方式提交:

Post方式的表單提交比Get方式更加安全,它不會把咱們要傳遞的參數顯示在URL裏,還有它能夠針對一些要傳遞內容比較大(好比文件上傳等);先經過一段代碼來演示此方式的提交;後面咱們再順便介紹Post方式提交時常遇到的一個錯誤;

首先一樣新建一個頁面(咱們把表單經過Post提交到PostPageResult.aspx頁面,method就是用來設置咱們使用Post方式):

 
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" action="PostPageResult.aspx" method="post">
    <div>
    Cnblogs帳號:<input type="text" size="20" name="Name" value="踏浪帥"/>
    <br />
    <input type="submit" value="提交" />
    </div>
    </form>
</body>
</html>
 

接收頁在的代碼(Post能夠採用Request.Form[Name]和Request[Name]進行接收參數,如果提交過來有上傳文件可使用 Request.Files進行得到跟處理):

            Response.Write("Post方式採用Request.Form[Name]:" + Request.Form["name"] + "</br>");

            Response.Write("Post方式採用Request[Name]:" + Request["name"]);

在使用Post常常會無心中碰到一個錯誤:

 

解決方式(當runat="server"的表單經過修改action提交數據到其它頁面時,也會引起這個問題;把表單中的runat="server"去掉);

 

網上還有其它解決的辦法:

a:添加enableEventValidation="false" enableViewStateMac="false"或在webconfig中添加<pages enableEventValidation="false" enableViewStateMac="false" />  

b:不使用跨頁面提交,提交到本頁後在page.load中redirect.  

c:使用 <asp:Button runat="server" PostBackUrl="~/Register/DoRegister.aspx" Text="提交" />

 

4:日常經過Request得到客戶端的Cookies值;

HttpCookie cookie = HttpContext.Current.Request.Cookies["HttpDemo"];

四:HttpContet對象之Response

1:Response理論知識:

Response表明了服務器響應對象。每次客戶端發出一個請求的時候,服務器就會用一個響應對象來處理這個請求,處理完這個請求以後,服務器就會銷燬這個相應對象,以便繼續接受其它客服端請求。

 

2:Response主要用來一些輸出的運用;只要簡單記住其幾個重要的屬性以及方法就差很少了;

 
    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.Redirect("Default.aspx");
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        string FileContent = Server.MapPath(".") + "\\TextFile.txt";
        Response.WriteFile(FileContent);
    }
    protected void Button3_Click(object sender, EventArgs e)
    {
        Response.Write("這是第一句");
        Response.End(); //中止運行,再也不執行任何語句 
        Response.Write("這是第二句");
        Response.Clear();  //清空緩衝區中的全部內容輸出
        Response.Close();//關閉當前服務器到客戶端的鏈接
    }
 

 Response還有個咱們常用到的地方是針對下載文件時輸出時的內容:

 
    public static void ResponseStream(Stream stream, string fileName)
    {
        if (stream.Length > 0)
        {
            try
            {
                long fileSize = stream.Length;
                System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";   //控制送出的文件類型
                System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", " attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));//向響應輸出流增長HTTP頭信息
                System.Web.HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
                byte[] fileBuffer = new byte[fileSize];
                stream.Read(fileBuffer, 0, (int)fileSize);
                stream.Close();
                System.Web.HttpContext.Current.Response.BinaryWrite(fileBuffer);
                System.Web.HttpContext.Current.Response.End();

            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
 

針對Response.ContentType是表示送出的文件類型(下在咱們列出一些比較常見的類型,其它類型能夠到網絡上進行搜索):

 
'doc' => 'application/msword', 
'bin' => 'application/octet-stream',  
'exe' => 'application/octet-stream', 
'dll' => 'application/octet-stream',  
'pdf' => 'application/pdf',  
'xls' => 'application/vnd.ms-excel', 
'ppt' => 'application/vnd.ms-powerpoint', 
'zip' => 'application/zip', 
'mp3' => 'audio/mpeg', 
'wav' => 'audio/x-wav', 
'pdb' => 'chemical/x-pdb', 
'bmp' => 'image/bmp', 
'gif' => 'image/gif', 
'ief' => 'image/ief', 
'jpeg' => 'image/jpeg', 
'jpg' => 'image/jpeg', 
'jpe' => 'image/jpeg', 
'png' => 'image/png', 
 

另外當咱們在寫入Cookies時經過Response的Set-Cookie向客戶端設置的Cookie;

        HttpCookie ck = new HttpCookie("HttpDemo");
        ck.Values.Add("UserID", "踏浪帥");
        Response.SetCookie(ck);
        Response.Redirect("Default.aspx");

五:HttpContet對象之Sever

1:Server理論知識:

Server對象是用於獲取服務器的相關信息的對象

2:對於Server對象咱們也是簡單的瞭解一些它的屬性內容;

 
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.Append("獲取計算機名:"+HttpContext.Current.Server.MachineName+"</br>");
        strBuilder.Append("獲取指定相對路徑在服務器上的物理路徑:" + Server.MapPath(".") + "</br>");
        strBuilder.Append("在服務器裏實現跳轉;不用再返回客戶端;Server.Transfer(string Path)</br>");
        strBuilder.Append("先執行路徑所表明的URL,而後執行完以後再執行本頁:Server.Execute(string Path)</br>");
        strBuilder.Append("對特殊字符串的處理:Server.HtmlDecode(string s)與Server.HtmlEncode(string s)</br>");
        strBuilder.Append("對URL路徑字符串進行編解碼:Server.UrlDecode(string s)與Server.UrlEncode(string s)</br>");
        Response.Write(strBuilder.ToString());
相關文章
相關標籤/搜索