Как использовать MVC 3 @Html.ActionLink внутри С# кода

Я хочу вызвать метод @Html.ActionLink внутри функции С#, чтобы вернуть строку со ссылкой на нее.

Что-то вроде этого:

string a = "Email is locked, click " + @Html.ActionLink("here to unlock.", "unlock") ;

Ответы

Ответ 1

Предполагая, что вы хотите выполнить это в своем контроллере, есть несколько обручей, которые нужно перепрыгнуть. Вы должны создать экземпляр ViewDataDictionary и TempDataDictionary. Затем вам нужно взять ControllerContext и создать IView. Наконец, вы готовы создать свой HtmlHelper, используя все эти элементы (плюс ваш RouteCollection).

После того, как вы все это сделали, вы можете использовать LinkExtensions.ActionLink для создания своей настраиваемой ссылки. По вашему мнению, вам нужно будет использовать @Html.Raw() для отображения ваших ссылок, чтобы предотвратить их кодирование в формате HTML. Вот нужный код:

var vdd = new ViewDataDictionary();
var tdd = new TempDataDictionary();
var controllerContext = this.ControllerContext;
var view = new RazorView(controllerContext, "/", "/", false, null);
var html = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()),
     new ViewDataContainer(vdd), RouteTable.Routes);
var a = "Email is locked, click " + LinkExtensions.ActionLink(html, "here to unlock.", "unlock", "controller").ToString();

Продемонстрировав все это, я предоставлю вам предостережение о том, что для вас это гораздо лучше. Добавьте в свою ViewModel ошибку и другую информацию, затем введите код для создания ссылки. Если это необходимо для нескольких видов, создайте HtmlHelper для создания ссылки.

UPDATE

Чтобы обратиться к one.beat.consumer, мой первоначальный ответ был примером того, что возможно. Если разработчику необходимо повторно использовать эту технику, сложность может быть скрыта в статическом помощнике, например:

public static class ControllerHtml
{
    // this class from internal TemplateHelpers class in System.Web.Mvc namespace
    private class ViewDataContainer : IViewDataContainer
    {
        public ViewDataContainer(ViewDataDictionary viewData)
        {
            ViewData = viewData;
        }

        public ViewDataDictionary ViewData { get; set; }
    }

    private static HtmlHelper htmlHelper;

    public static HtmlHelper Html(Controller controller)
    {
        if (htmlHelper == null)
        {
            var vdd = new ViewDataDictionary();
            var tdd = new TempDataDictionary();
            var controllerContext = controller.ControllerContext;
            var view = new RazorView(controllerContext, "/", "/", false, null);
            htmlHelper = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()),
                 new ViewDataContainer(vdd), RouteTable.Routes);
        }
        return htmlHelper;
    }

    public static HtmlHelper Html(Controller controller, object model)
    {
        if (htmlHelper == null || htmlHelper.ViewData.Model == null || !htmlHelper.ViewData.Model.Equals(model))
        {
            var vdd = new ViewDataDictionary();
            vdd.Model = model;
            var tdd = new TempDataDictionary();
            var controllerContext = controller.ControllerContext;
            var view = new RazorView(controllerContext, "/", "/", false, null);
            htmlHelper = new HtmlHelper(new ViewContext(controllerContext, view, vdd, tdd, new StringWriter()),
                 new ViewDataContainer(vdd), RouteTable.Routes);
        }
        return htmlHelper;
    }
}

Затем в контроллере он используется так:

var a = "Email is locked, click " + 
    ControllerHtml.Html(this).ActionLink("here to unlock.", "unlock", "controller").ToString();

или так:

var model = new MyModel();
var text = ControllerHtml.Html(this, model).EditorForModel();

В то время как легче использовать Url.Action, теперь это расширяется в мощный инструмент для создания любой надстройки в контроллере, используя все HtmlHelpers (с полным Intellisense).

Возможности использования включают создание разметки с использованием моделей и шаблонов редакторов для электронных писем, генерации PDF файлов, доставки документов в режиме онлайн и т.д.

Ответ 2

Вы можете создать метод расширения HtmlHelper:

public static string GetUnlockText(this HtmlHelper helper)
{
    string a = "Email is locked, click " + helper.ActionLink("here to unlock.", "unlock");
    return a;
}

или если вы хотите создать эту ссылку за пределами области aspx-страницы, вам нужно будет создать ссылку на HtmlHelper и затем сгенерировать. Я делаю это в статическом классе UrlUtility (я знаю, люди ненавидят статические классы и слово "Утилита", но стараются сосредоточиться). Перегрузка при необходимости:

public static string ActionLink(string linkText, string actionName, string controllerName)
{
    var httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
    var requestContext = new RequestContext(httpContext, new RouteData());
    var urlHelper = new UrlHelper(requestContext);

    return urlHelper.ActionLink(linkText, actionName, controllerName, null);
}

Затем вы можете написать следующее из того места, где пожелает ваше сердце:

string a = "Email is locked, click " + UrlUtility.ActionLink("here to unlock.", "unlock", "controller");

Ответ 3

Там пара вещей плохо об этих других ответах...

Акустический ответ требует, чтобы вы ввели пространство имен LinkExtensions в С#, что не так, но нежелательно для меня.

Идея Хантера о создании помощника лучше, но все же писать вспомогательную функцию для одного URL-адреса громоздка. Вы могли бы написать помощника, который поможет вам создавать строки, которые принимают параметры, или вы могли бы просто сделать это по-старому:

var link = "Email is... click, <a href=\"" + Url.Action("action") + "\"> to unlock.</a>";

@counsellorben,

я не вижу причин для сложности; пользователь хочет только отобразить маршрутизацию действий в жесткую строку, содержащую тег привязки. Более того, ActionLink() в жесткой конкатенированной строке ничего не покупает и заставляет разработчика использовать LinkExtensions, которые предназначены для представлений.

Если пользователь не согласен с использованием ActionLink() или не нуждается (по какой-то причине), чтобы вычислить эту строку в конструкторе, сделать это в представлении намного лучше.

Я все еще поддерживаю и рекомендую ответы tvanfosson, и я предоставил.

Ответ 4

Лучше всего построить ссылку вручную, используя UrlHelper, доступный в контроллере. Сказав это, я с подозрением отношусь к тому, что, вероятно, лучший способ справиться с этим в представлении или частичном представлении, обмениваться или иным образом.

string a = "Email is locked, click <a href=\""
              + Url.Action( "unlock" )
              + "\">here to unlock.</a>";

Ответ 5

Возможно, попробуйте следующее:

string a = "Email is locked, click " + System.Web.Mvc.Html.LinkExtensions.ActionLink("here to unlock.", "unlock");