2010-09-14 44 views
2

我的應用程序發送一些電子郵件,並且電子郵件中引用的圖像路徑需要根據用戶如何訪問發送電子郵件的頁面而有所不同。我使用的代碼的變化之前,沒有任何問題很多次,但是這是我第一次嘗試做它在MVC應用程序:ASP.NET MVC - HttpRequestWrapper.Url是否爲空?

var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images"); 
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri; 

第二行拋出,因爲HttpContext的一個NullReferenceException異常。 Request.Url爲空。怎麼可能?

編輯:我應該注意到,我在與處理請求的線程池線程分開的線程池線程中運行此代碼。如果我將這段代碼移回執行控制器動作的線程,那麼url就在那裏。現在,我已經訴諸於在同一個線程上執行代碼。

回答

0

的HttpContext可能並不總是在線程訪問。您需要將所需的信息傳遞給線程:

var relImagePath = controllerContext.HttpContext.Response.ApplyAppPathModifier("~/Emails/Images"); 
var absImagePath = new Uri(controllerContext.HttpContext.Request.Url, relImagePath).AbsoluteUri; 
new Thread(state => 
{ 
    var imagePath = (string)state; 
    // TODO ... 
}).Start(absImagePath); 

,或者如果你正在使用線程池(僅適用於短期運行的任務):

ThreadPool.QueueUserWorkItem(state => 
{ 
    var imagePath = (string)state; 
    // TODO ... 
}, absImagePath); 
0

我會假設RequestContext在調用controllerContext.HttpContext時獲取當前的HttpContext(因爲它要求RequestContext爲HttpContext),我想它可能只是詢問HttpContext.Current,這就是爲什麼得到null。

嘗試在ASP.NET線程中抓住controllerContext.HttpContext,將其保存並傳遞到您自己的線程,而不是稍後在錯誤時間要求HttpContext的控制器上下文。

這是我的猜測。

此外,http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx

+0

我懷疑你是正確的時間獲得HttpContext的時間。我會研究一下。不過,我也想對你們聯繫的文章發表評論,說我強烈反對它的整體情緒。對於長時間運行的任務使用線程池可能是阻止ASP.NET工作者隊列的一種可靠的方式,但對於許多短暫的「火災和遺忘」類型任務,線程池是最理想的工具,並創建一個無限數量其他線程幾乎不是一個好主意。 – Chris 2010-09-15 00:20:51

0

這種覆蓋也似乎工作:

protected new UrlHelper Url 
     { 
      get { return base.Url ?? (base.Url = new UrlHelper(ControllerContext.RequestContext)); } 
      set { base.Url = value; } 
     }