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

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

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

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

5 ответов


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

обновление

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

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


вы можете создать метод расширения 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>";

@counsellorben,

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

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

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


лучше всего построить ссылку вручную, используя 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");