日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HttpContext 来源(System.Web.HttpContext.Current值为null的问题)

發(fā)布時(shí)間:2024/1/17 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HttpContext 来源(System.Web.HttpContext.Current值为null的问题) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)大神文檔:https://www.cnblogs.com/linJie1930906722/p/5708966.html

ASP.NET提供了靜態(tài)屬性System.Web.HttpContext.Current,因此獲取HttpContext對(duì)象就非常方便了。也正是因?yàn)檫@個(gè)原因,所以我們經(jīng)常能見(jiàn)到直接訪問(wèn)System.Web.HttpContext.Current的代碼:

1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Web;5 6 namespace Test_HttpContext.Current7 {8 public class Test9 { 10 11 public Test() 12 { 13 string file =System.Web.HttpContext.Current.Request.MapPath("~/App_Data/1.xml"); 14 15 string text = System.IO.File.ReadAllText(file); 16 17 //..........其它的操作 18 } 19 20 // 或者在一些方法中直接使用HttpContext.Current 21 public void Test_1() 22 { 23 string url = System.Web.HttpContext.Current.Request.RawUrl; 24 25 string username = System.Web.HttpContext.Current.Session["username"].ToString(); 26 27 string value = (string)System.Web.HttpContext.Current.Items["key"]; 28 } 29 30 // 甚至還設(shè)計(jì)成靜態(tài)屬性 31 public static string Test_2 32 { 33 get 34 { 35 return (string)System.Web.HttpContext.Current.Items["XXX"]; 36 } 37 } 38 39 /// <summary> 40 /// 獲取文件絕對(duì)路徑 41 /// </summary> 42 /// <param name="fileName">文件名稱</param> 43 /// <returns></returns> 44 public string Test_3(string fileName) 45 { 46 return System.Web.HttpContext.Current.Server.MapPath("~/Log" + fileName); 47 } 48 49 } 50 }

上面的這些代碼這樣寫真的沒(méi)有問(wèn)題嗎?
答案是否定的

請(qǐng)看下面的驗(yàn)證:

我們先來(lái)看看HttpContext到底存儲(chǔ)在哪里:

1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Web;5 using System.Web.UI;6 using System.Web.UI.WebControls;7 8 namespace Test_HttpContext.Current9 { 10 public partial class WebForm1 : System.Web.UI.Page 11 { 12 protected void Page_Load(object sender, EventArgs e) 13 { 14 15 HttpContext context1 = System.Web.HttpContext.Current; 16 17 HttpContext context2 = System.Runtime.Remoting.Messaging.CallContext.HostContext as HttpContext; //當(dāng)前(請(qǐng)求)線程上下文 18 19 bool isEqual = object.ReferenceEquals(context1, context2); 20 21 Response.Write("context1與context2是否相同的實(shí)例:" + isEqual); 22 } 23 } 24 }

上面的代碼運(yùn)行的結(jié)果是true:

從這段代碼來(lái)看,HttpContext其實(shí)是保存在System.Runtime.Remoting.Messaging.CallContext.HostContext這個(gè)屬性中, System.Runtime.Remoting.Messaging.CallContext.HostContext在MSDN的解釋是 獲取或設(shè)置與當(dāng)前線程相關(guān)聯(lián)的主機(jī)上下文

我們?cè)谝粋€(gè)ASP.NET程序中,為什么可以到處訪問(wèn)HttpContext.Current呢?
因?yàn)锳SP.NET會(huì)為每個(gè)請(qǐng)求分配一個(gè)線程(也是當(dāng)前線程),這個(gè)線程會(huì)執(zhí)行我們的代碼來(lái)生成響應(yīng)結(jié)果, 即使我們的代碼散落在不同的地方(類庫(kù)),線程仍然會(huì)執(zhí)行它們, 所以我們可以在任何地方訪問(wèn)System.Web.HttpContext.Current獲取到與當(dāng)前請(qǐng)求相關(guān)的HttpContext對(duì)象, 這些代碼是由同一個(gè)線程來(lái)執(zhí)行,所以得到的HttpContext引用也就是我們期待的那個(gè)與請(qǐng)求相關(guān)的對(duì)象。

當(dāng)前線程是什么意思??
我的理解是:
1. 當(dāng)前線程是指與當(dāng)前請(qǐng)求相關(guān)的線程。
2. 在ASP.NET程序中,有些線程并非總是與請(qǐng)求相關(guān)。

雖然在ASP.NET程序中,幾乎所有的線程都應(yīng)該是為響應(yīng)請(qǐng)求而運(yùn)行的,但是還有一些線程卻不是為了響應(yīng)請(qǐng)求而(產(chǎn)生)運(yùn)行的,

例如:
1. 定時(shí)器的回調(diào)。
2. Cache的移除通知。
3. APM模式下異步完成回調(diào)。
4. 主動(dòng)創(chuàng)建線程或者將任務(wù)交給線程池來(lái)執(zhí)行。

5.異步任務(wù)Task

至于什么APM網(wǎng)上資料很多,這里我就不說(shuō)明了

在這些情況下使用System.Web.HttpContext.Current獲取HttpContext對(duì)象得到的結(jié)果都是null,因?yàn)樘幚硭麄兊木€程不是當(dāng)前線程(為處理請(qǐng)求產(chǎn)生線程)

說(shuō)的這里我們?cè)倩仡^看看本文開(kāi)始寫的(部分)代碼:

1 /// <summary> 2 /// 獲取文件絕對(duì)路徑 3 /// </summary> 4 /// <param name="fileName">文件名稱</param> 5 /// <returns></returns> 6 public string Test_3(string fileName) 7 { 8 return System.Web.HttpContext.Current.Server.MapPath("~/Log" + fileName); 9 }

如果這段代碼在那5種情況下運(yùn)行,都會(huì)拋空指針異常,因?yàn)镾ystem.Web.HttpContext.Current得到是null。

為什么會(huì)得到null呢?

因?yàn)檫\(yùn)行這段代碼線程不是處理當(dāng)前請(qǐng)求的當(dāng)前線程

為什么其他地方得到又不是null呢?

因?yàn)锳SP.NET程序在調(diào)用您的代碼前,已經(jīng)將HttpContext對(duì)象設(shè)置到前面所說(shuō)的System.Runtime.Remoting.Messaging.CallContext.HostContext屬性中。

HttpApplication有個(gè)內(nèi)部方法OnThreadEnter(),ASP.NET在調(diào)用外部代碼前會(huì)調(diào)用這個(gè)方法來(lái)切換HttpContext, 例如:每當(dāng)執(zhí)行管線的事件處理器之前,或者同步上下文(AspNetSynchronizationContext)執(zhí)行回調(diào)時(shí)。 切換線程的CallContext.HostContext屬性之后,我們的代碼就可以訪問(wèn)到HttpContext引用。 注意:HttpContext的引用其實(shí)是保存在HttpApplication對(duì)象中。

?

這種情況下該如何獲取文件的絕對(duì)路徑呢?

我們可以訪問(wèn)System.Web.HttpRuntime.AppDomainAppPath獲取程序的根路徑,然后再拼接文件的相對(duì)路徑即可

上面的代碼得到的HttpContext對(duì)象是null,再調(diào)用MapPath來(lái)獲取站點(diǎn)根目錄,就必死無(wú)疑了!

所以在此建議大家在獲取程序(站點(diǎn))的根目錄時(shí)盡量使用System.Web.HttpRuntime.AppDomainAppPath進(jìn)行獲取站點(diǎn)的根目錄

?

那么在異步調(diào)用調(diào)用時(shí)訪問(wèn)HttpContext對(duì)象呢?

前面我還提到在APM模式下的異步完成回調(diào)時(shí),訪問(wèn)HttpContext.Current也會(huì)返回null,那么此時(shí)該怎么辦呢?
1. 在類型中添加一個(gè)字段來(lái)保存HttpContext的引用(異步開(kāi)始前)。
2. 將HttpContext賦值給BeginXXX方法的最后一個(gè)參數(shù)(object state)

建議優(yōu)先選擇第二種方法,因?yàn)榭梢苑乐挂院笏司S護(hù)時(shí)數(shù)據(jù)成員被意外使用。

?

轉(zhuǎn)載于:https://www.cnblogs.com/janeaiai/p/8794066.html

總結(jié)

以上是生活随笔為你收集整理的HttpContext 来源(System.Web.HttpContext.Current值为null的问题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。