[MVC] 升到.NET Framework 4.5 後,使用WebRequest post,Thread的變化

[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

這個部份到底做了什麼事,只有先記錄下來。