2010-09-13 24 views
3

我有一個線程發送電子郵件。我需要生成ActionLinks作爲電子郵件內容的一部分,以便用戶可以點擊鏈接並將其重定向到網站,完全符合所需頁面。我嘗試實例化一個UrlHelper類,並使用它的Action方法來生成鏈接,但由於線程不在任何請求的上下文中運行,因此在生成ActionLink時收到異常。如何在線程中生成ActionLink

我該怎麼做?

+0

可能重複[ASP.NET MVC:如何創建一個可用UrlHelper實例](http://stackoverflow.com/questions/2412773/asp-net-mvc-how-to-create-a -usable-urlhelper-instance) – bzlm 2010-09-14 13:42:31

回答

1

您需要假HttpContextBase並通過這一個UrlHelper,你可以在一個線程中使用沒有的HttpContext。這裏是粗略的想法,雖然你需要圍繞它創建一個類,但這是一個概念的快速證明,因爲單元測試沒有HttpContext。

[TestFixture] 
public class RouteTestClass 
{ 
    private UrlHelper helper; 

    public RouteTestClass() 
    { 
     MvcApplication.RegisterRoutes(RouteTable.Routes); //You dont need to do this if its done in global.asax! 
     var c = new RequestContext(new FakeContext(), new RouteData()); 
     helper = new UrlHelper(c, RouteTable.Routes); 
    } 

    [Test] 
    public void TestGetHomeIndex() 
    { 
     var url = helper.Action("Index", "Home"); 
     Assert.AreEqual("/",url); 
    } 
} 

public class FakeContext : HttpContextBase 
{ 
    public override HttpRequestBase Request { get { return new FakeRequest(); } } 
    public override HttpResponseBase Response { get { return new FakeResponse(); } } 
} 

public class FakeRequest : HttpRequestBase 
{ 
    public override string ApplicationPath { get { return "/"; } } 
    public override NameValueCollection ServerVariables { get { return new NameValueCollection(); } } 
} 

public class FakeResponse : HttpResponseBase 
{ 
    public override string ApplyAppPathModifier(string virtualPath) 
    { 
     return virtualPath; 
    } 
} 

編輯

看着this答案,我整理的代碼了一點,因爲我並不需要創建HttpRequestBase和HttpResponseBase自己假貨。

[TestFixture] 
public class RouteTestClass 
{ 
    private UrlHelper helper; 

    public RouteTestClass() 
    { 
     MvcApplication.RegisterRoutes(RouteTable.Routes); 
     var req = new HttpRequest("/", "http://www.yoururl.com", ""); 
     var resp = new HttpResponse(new StringWriter()); 
     var httpContext = new HttpContext(req, resp); 
     var c = new RequestContext(new HttpContextWrapper(httpContext), new RouteData()); 
     helper = new UrlHelper(c, RouteTable.Routes); 
    } 

    [Test] 
    public void TestGetHomeIndex() 
    { 
     var url = helper.Action("Index", "Home"); 
     Assert.AreEqual("/",url); 
    } 
} 
+0

這是一個kickass答案。我會盡力謝謝 – Roman 2010-09-17 16:01:26

0

您可以通過將線程傳遞給線程啓動器,讓線程訪問現有的UrlHelper。如果你的線程是由控制器開始,只是通過UrlHelper在控制器的Url屬性:

new Thread(
    urlHelper => 
    { 
     var url = 
      ((UrlHelper)urlHelper) 
      .Action("Index", "Home", new { Id = 5 }); 
     // use url here 
    } 
).Start(Url); 
+0

很好的答案,但我的線程是在應用程序啓動時創建的。 – Roman 2010-09-14 13:00:23

相關問題