[MVC] 升到.NET Framework 4.5 後,使用WebRequest post,Thread的變化
這是我們產品開發最近才發現的一個有趣的現象,一般而言是不會有人會遇到這鬼問題,
情境 : 站台開放一個API端口接收Json data,如 : 別人使用WebRequest post json data
MVC 執行生命週期 : 這有一大串我挑兩個點就是 Route Handler –> Controller
(請參考WILL保哥:http://mnp.longsun.net/event_site_download/slides/100225/asp_net_mvc.pdf) 直接貼連結若有不妥麻煩告知感謝
程式 :
private void FadesPost()
{
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
WebRequest request = WebRequest.Create("http://localhost:54275/iStore/Fades/API.mvc/Index");
request.Method = "POST";
//request.ContentType的設定會有不同的情況
request.ContentType = "application/json";//post json data當然會這樣設定
// request.ContentType = "application/x-www-form-urlencoded"; //一般情況
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
}
站台接口 :
我在Route Handler 跟Controller Action 裡面,把System.Threading.Thread.CurrentThread.ManagedThreadId記到我的Log裡
結果 :
當WebRequest 的 ContentType = "application/json" 時:
2012-10-18 10:25:52,182 [20] INFO QuartzLogger [(null)] - RouteHandler Thread ID : 20
2012-10-18 10:25:52,182 [20] INFO QuartzLogger [(null)] - Global PreRequestHandlerExecute Thread ID : 20
2012-10-18 10:25:52,182 [7] INFO QuartzLogger [(null)] - Controller Index Thread ID : 7
由於當時我們產品其他接口都沒問題,唯一差別就是ContentType所以索性不管資料先更改ContentType測看看
當WebRequest 的 ContentType = "application/x-www-form-urlencoded" 時:
2012-10-18 10:27:15,586 [6] INFO QuartzLogger [(null)]–RouteHandler Thread ID : 6
2012-10-18 10:27:15,587 [6] INFO QuartzLogger [(null)]–Global PreRequestHandlerExecute Thread ID : 6
2012-10-18 10:27:15,588 [6] INFO QuartzLogger [(null)]–Controller Index Thread ID : 6
為什麼我們會去在意在這個生命週期間Thread的變化,原因是因為我們在RouteHandler時,
會把一些資訊存到LogicalThreadContext裡,若到了Controller時Thread不是同一個,
則LogicalThreadContext當然就取不到我們所要的資料。
之後... :
因為以前沒有發生這種怪事,所以我們懷疑到底是不是有可能升級MVC 4時,NET Framework 4.5搞的鬼,
所以我們找了一台環境是NET Framework 4.0的機器,建了兩個站台,一個發怖MVC3,一個發怖MVC4,
MVC4要架在NET Framework 4.0的環境下是有點奇怪,我是把所有MVC4相關的dll全都硬貼到它的bin底下,
讓它能動就可,經測試結果不管是MVC3的站台或是MVC4的站台,在這兩個生命週期內Thread ID 都一致。
由於這是個非常冷門又很難有機會碰到的情境,所以我並沒有找到相關說明NET Framework 4.0 到 NET Framework 4.5
這個部份到底做了什麼事,只有先記錄下來。