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


Я хочу вызвать @Html.Метод ActionLink внутри функции c# для возврата строки со ссылкой на нее.

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

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

5 ответов:

Предполагая, что вы хотите выполнить это в своем контроллере, есть несколько обручей, через которые нужно перепрыгнуть. Вы должны создать экземпляры a ViewDataDictionary и a 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 для создания ссылки.

Обновить

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

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, on-line доставка документов и т. д.

Можно создать метод расширения 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 (я знаю, люди ненавидят статические классы и слово Utility, но стараются сосредоточиться). Перегрузка по мере необходимости:

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");

Есть пара плохих вещей в этих других ответах...

Ответ Shark требует, чтобы Вы перенесли пространство имен LinkExtensions в C#, что не является неправильным, но нежелательным для меня.

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

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

@advisellorben,

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

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

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

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

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

Может быть, попробуем так:

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