Как создать ActionLink внутри темы - PullRequest
3 голосов
/ 13 сентября 2010

У меня есть тема, которая рассылает электронные письма. Мне нужно создать ActionLinks как часть содержимого электронного письма, чтобы пользователь мог щелкнуть ссылку и перейти на веб-сайт точно на нужную страницу. Я попытался создать экземпляр класса UrlHelper и использовать его метод Action для генерации ссылки, но поскольку потоки не выполняются в контексте любого запроса, я получаю исключения во время создания ActionLink.

Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 17 сентября 2010

Вам необходимо подделать 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;
    }
}

Редактировать

Глядя на этот ответ, я немного исправил код, так как мне не нужно создавать подделки для 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 голосов
/ 14 сентября 2010

Вы можете предоставить потоку доступ к существующему UrlHelper, передав его в пускатель потока.Если ваш поток запускается с контроллера, просто передайте UrlHelper в свойстве Url контроллера:

new Thread(
    urlHelper =>
    {
        var url = 
            ((UrlHelper)urlHelper)
            .Action("Index", "Home", new { Id = 5 });
        // use url here
    }
).Start(Url);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...