[c#] Obteniendo la URL completa de acción en ASP.NET MVC


Answers

Como UrlHelper.Action() Paddy: si usas una sobrecarga de UrlHelper.Action() que explícitamente especifica el protocolo a usar, la URL generada será absoluta y completamente calificada en lugar de ser relativa.

Escribí una publicación de blog llamada Cómo construir URLs de acción absoluta utilizando la clase UrlHelper en la que sugiero que se escriba un método de extensión personalizado por el bien de la legibilidad:

/// <summary>
/// Generates a fully qualified URL to an action method by using
/// the specified action name, controller name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="actionName">The name of the action method.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteAction(this UrlHelper url,
    string actionName, string controllerName, object routeValues = null)
{
    string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;

    return url.Action(actionName, controllerName, routeValues, scheme);
}

Entonces puedes simplemente usarlo así en tu vista:

@Url.AbsoluteAction("Action", "Controller")
Question

Esta pregunta ya tiene una respuesta aquí:

¿Hay una forma incorporada de obtener la URL completa de una acción?

Estoy buscando algo como GetFullUrl("Action", "Controller") que devolvería algo como http://www.fred.com/Controller/Action .

El motivo por el que busco esto es evitar las URL de codificación rígida en los correos electrónicos automáticos que se generan para que las URL siempre se puedan generar en relación con la ubicación actual del sitio.




Esta pregunta es específica de ASP .NET. Sin embargo, estoy seguro de que algunos de ustedes se beneficiarán de javascript independiente del sistema que es beneficioso en muchas situaciones.

ACTUALIZACIÓN: la forma de obtener URL fuera de la página está bien descrita en las respuestas anteriores.

O podría hacer un oneliner como el siguiente:

new UrlHelper(actionExecutingContext.RequestContext).Action(
    "SessionTimeout", "Home", 
    new {area = string.Empty}, 
    actionExecutingContext.Request.Url!= null? 
    actionExecutingContext.Request.Url.Scheme : "http"
);

de filtro o:

new UrlHelper(this.Request.RequestContext).Action(
    "Details", 
    "Journey", 
    new { area = productType }, 
    this.Request.Url!= null? this.Request.Url.Scheme : "http"
);

Sin embargo, con bastante frecuencia uno necesita obtener la url de la página actual, para aquellos casos que usan Html.Action y poner el nombre y el controlador de la página en la que me encuentras se siente incómodo. Mi preferencia en tales casos es usar JavaScript en su lugar. Esto es especialmente bueno en sistemas que están medio reescritos MVT medio web-forms medio vb-script medio Dios sabe qué - y para obtener el URL de la página actual uno necesita usar un método diferente cada vez.

Una forma es usar JavaScript para obtener la URL es window.location.href another - document.URL




Puede que solo sea yo realmente exigente, pero solo me gusta definir constantes una vez. Si usa cualquiera de los enfoques definidos anteriormente, su constante de acción se definirá varias veces.

Para evitar esto, puede hacer lo siguiente:

    public class Url
    {
        public string LocalUrl { get; }

        public Url(string localUrl)
        {
            LocalUrl = localUrl;
        }

        public override string ToString()
        {
            return LocalUrl;
        }
    }

    public abstract class Controller
    {
        public Url RootAction => new Url(GetUrl());

        protected abstract string Root { get; }

        public Url BuildAction(string actionName)
        {
            var localUrl = GetUrl() + "/" + actionName;
            return new Url(localUrl);
        }

        private string GetUrl()
        {
            if (Root == "")
            {
                return "";
            }

            return "/" + Root;
        }

        public override string ToString()
        {
            return GetUrl();
        }
    }

Luego crea tus controladores, digamos por ejemplo el DataController:

    public static readonly DataController Data = new DataController();
    public class DataController : Controller
    {
        public const string DogAction = "dog";
        public const string CatAction = "cat";
        public const string TurtleAction = "turtle";

        protected override string Root => "data";

        public Url Dog => BuildAction(DogAction);
        public Url Cat => BuildAction(CatAction);
        public Url Turtle => BuildAction(TurtleAction);
    }

Entonces solo úsalo como:

    // GET: Data/Cat
    [ActionName(ControllerRoutes.DataController.CatAction)]
    public ActionResult Etisys()
    {
        return View();
    }

Y desde su .cshtml (o cualquier código)

<ul>
    <li><a href="@ControllerRoutes.Data.Dog">Dog</a></li>
    <li><a href="@ControllerRoutes.Data.Cat">Cat</a></li>
</ul>

Definitivamente este es mucho más trabajo, pero estoy tranquilo sabiendo que la validación en tiempo de compilación está de mi lado.






Related