如何在Threads中生成ActionLink

时间:2010-09-13 16:35:40

标签: asp.net asp.net-mvc asp.net-mvc-2

我有一个发送电子邮件的帖子。我需要生成ActionLinks作为电子邮件内容的一部分,以便用户可以单击该链接并重定向到网站,完全重定向到所需的页面。我试图实例化一个UrlHelper类并使用它的Action方法来生成链接,但由于线程不在任何请求的上下文中运行,因此在生成ActionLink时会出现异常。

我该怎么做?

2 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:0)

您可以通过将线程传递给线程启动器来为线程提供对现有UrlHelper的访问权限。如果您的线程是从控制器启动的,只需在控制器的UrlHelper属性中传递Url

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