Получение полного URL действия в ASP.NET MVC [дубликат]

этот вопрос уже есть ответ здесь:

есть ли встроенный способ получить полный URL-адрес действия?

Я ищу что-то вроде GetFullUrl("Action", "Controller") это вернуло бы что-то вроде http://www.fred.com/Controller/Action.

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

6 ответов


существует перегрузка Url.Действие, которое принимает желаемый протокол (например, http, https) в качестве аргумента - если вы укажете это, вы получите полный URL-адрес.

вот пример, который использует протокол текущего запроса в метод действия:

var fullUrl = this.Url.Action("Edit", "Posts", new { id = 5 }, this.Request.Url.Scheme);

HtmlHelper (@Html) также имеет перегрузку метода ActionLink, который можно использовать в razor для создания элемента привязки, но для этого также требуются параметры имени хоста и фрагмента. Поэтому я бы просто решил использовать @URL-адрес.Действие снова:

<span>
  Copy
  <a href='@Url.Action("About", "Home", null, Request.Url.Scheme)'>this link</a> 
  and post it anywhere on the internet!
</span>

как Пэдди отметил: если вы используете перегрузку UrlHelper.Action() который явно указывает используемый протокол, созданный URL-адрес будет абсолютным и полным, а не относительным.

Я написал сообщение в блоге под названием как построить абсолютные URL-адреса действий с помощью класса UrlHelper в котором я предлагаю написать пользовательский метод расширения для удобства чтения:

/// <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);
}

вы можете просто использовать его как это в вашем вид:

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

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

чтобы избежать этого, вы можете сделать следующее:

    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();
        }
    }

затем создайте свои контроллеры, например, 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);
    }

тогда просто используйте его как:

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

и из вашего .cshtml (или любой код)

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

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


Это то, что вам нужно сделать.

@Url.Action(action,controller, null, Request.Url.Scheme)

У меня была проблема с этим, мой сервер работал за балансировщиком нагрузки. Балансировщик нагрузки завершал соединение SSL / TLS. Затем он передал запрос на веб-серверы с помощью http.

используя Url.Метод Action () с запросом.Url-адрес.Схема, она продолжала создавать HTTP-url, в моем случае, чтобы создать ссылку в автоматическом электронном письме (что моему PenTester не понравилось).

Я, возможно, немного обманул, но это именно то, что мне нужно, чтобы заставить https URL-адрес:

<a href="@Url.Action("Action", "Controller", new { id = Model.Id }, "https")">Click Here</a>

Я на самом деле использовать веб.config AppSetting, поэтому я могу использовать http при отладке локально, но все среды тестирования и prod используют преобразование для установки значения https.


этот вопрос специфичен для ASP .NET, однако я уверен, что некоторые из вас выиграют от системного агностического javascript, который полезен во многих ситуациях.

обновление: способ получения url-адреса, сформированного вне самой страницы, хорошо описан в ответах выше.

или вы можете сделать oneliner следующим образом:

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

от фильтра или:

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

однако довольно часто нужно получить url текущей страницы, для тех случаи использования Html.Action и поставить его имя и контроллер страницы, в которой вы находитесь, мне неудобно. В таких случаях я предпочитаю использовать JavaScript. Это особенно хорошо в системах, которые наполовину переписаны MVT, наполовину веб-формы, наполовину VB-скрипт, наполовину Бог знает что - и для получения URL текущей страницы нужно каждый раз использовать другой метод.

один из способов - использовать JavaScript для получения URL-адреса window.location.href другой - document.URL