我有一個線程發送電子郵件。我需要生成ActionLinks作爲電子郵件內容的一部分,以便用戶可以點擊鏈接並將其重定向到網站,完全符合所需頁面。我嘗試實例化一個UrlHelper
類,並使用它的Action
方法來生成鏈接,但由於線程不在任何請求的上下文中運行,因此在生成ActionLink時收到異常。如何在線程中生成ActionLink
我該怎麼做?
我有一個線程發送電子郵件。我需要生成ActionLinks作爲電子郵件內容的一部分,以便用戶可以點擊鏈接並將其重定向到網站,完全符合所需頁面。我嘗試實例化一個UrlHelper
類,並使用它的Action
方法來生成鏈接,但由於線程不在任何請求的上下文中運行,因此在生成ActionLink時收到異常。如何在線程中生成ActionLink
我該怎麼做?
您需要假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);
}
}
的
這是一個kickass答案。我會盡力謝謝 – Roman 2010-09-17 16:01:26
您可以通過將線程傳遞給線程啓動器,讓線程訪問現有的UrlHelper
。如果你的線程是由控制器開始,只是通過UrlHelper
在控制器的Url
屬性:
new Thread(
urlHelper =>
{
var url =
((UrlHelper)urlHelper)
.Action("Index", "Home", new { Id = 5 });
// use url here
}
).Start(Url);
很好的答案,但我的線程是在應用程序啓動時創建的。 – Roman 2010-09-14 13:00:23
可能重複[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