Generar URL en ayuda HTML

168

Normalmente en una vista ASP.NET se podría usar la siguiente función para obtener una URL (no una <a>):

Url.Action("Action", "Controller");

Sin embargo, no puedo encontrar cómo hacerlo desde un asistente HTML personalizado. yo tengo

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

La variable auxiliar tiene los métodos Action y GenerateLink, pero generan <a>los de. Cavé un poco en el código fuente ASP.NET MVC, pero no pude encontrar una manera directa.

El problema es que la Url anterior es miembro de la clase de vista y para su creación de instancias necesita algunos contextos y mapas de ruta (con los que no quiero tratar y no se supone que lo haga de todos modos). Alternativamente, la instancia de la clase HtmlHelper también tiene algún contexto que supongo que es la cena del subconjunto de la información de contexto de la instancia de Url (pero nuevamente no quiero tratar con ella).

En resumen, creo que es posible, pero dado que todas las formas en que pude ver, implican alguna manipulación con algunas cosas más o menos internas de ASP.NET, me pregunto si hay una mejor manera.

Editar: por ejemplo, una posibilidad que veo sería:

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

Pero no parece correcto. No quiero tratar con instancias de UrlHelper yo mismo. Debe haber una manera más fácil.

Jan Zich
fuente
3
Me doy cuenta de que este es un ejemplo simplificado, pero para el ejemplo que se muestra, ampliaría UrlHelper en lugar de HtmlHelper. Sin embargo, su código real puede necesitar ambos.
Craig Stuntz
Lo siento, debería haber sido más claro: quería hacer un procesamiento HTML en el método de extensión y necesitaba generar URL para ello.
Jan Zich

Respuestas:

217

Puede crear un asistente de URL como este dentro del método de extensión de ayuda html:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")
Darin Dimitrov
fuente
2
Creo que sería mejor si el constructor también inicializa RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1
22

También puede obtener enlaces usando UrlHelperla clase pública y estática:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

En este ejemplo, no tiene que crear una nueva clase UrlHelper, lo que podría ser una pequeña ventaja.

cryss
fuente
Me gusta más esta respuesta porque establece RouteCollection.
kpull1
10

Aquí está mi pequeño método de extensión para obtener UrlHelperuna HtmlHelperinstancia:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

Úselo como:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(Estoy publicando este ans solo como referencia)

Kibria
fuente
Excelente enfoque porque reutiliza un objeto existente en lugar de crear uno nuevo.
Mike
Estamos utilizando ASP.NET 4.5 y experimentamos problemas de reencuentro. No creemos que UrlHelper sea reutilizable en las solicitudes http. Por favor toma nota.
Carl en 't Veld