Получение полного 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>
этот это определенно намного больше работы, но я отдыхаю, зная, что проверка времени компиляции на моей стороне.
У меня была проблема с этим, мой сервер работал за балансировщиком нагрузки. Балансировщик нагрузки завершал соединение 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