В MVC 5 у меня были следующие методы расширения для генерации абсолютных URL-адресов вместо относительных:
public static class UrlHelperExtensions
{
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);
}
public static string AbsoluteContent(
this UrlHelper url,
string contentPath)
{
return new Uri(url.RequestContext.HttpContext.Request.Url, url.Content(contentPath)).ToString();
}
public static string AbsoluteRouteUrl(
this UrlHelper url,
string routeName,
object routeValues = null)
{
string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;
return url.RouteUrl(routeName, routeValues, scheme);
}
}
Что было бы эквивалентом в ASP.NET Core?
UrlHelper.RequestContext
более не существует.- Вы не можете получить объект, так
HttpContext
как больше не существует статическогоHttpContext.Current
свойства.
Насколько я понимаю, теперь вам также потребуется передать объекты HttpContext
или HttpRequest
. Я прав? Есть ли способ получить текущий запрос?
Я даже на правильном пути, должен ли домен теперь быть переменной среды, которая просто добавляется к относительному URL-адресу? Было бы это лучше?
c#
asp.net-core
Мухаммад Рехан Саид
источник
источник
http://example.com/controller/action
Ответы:
После RC2 и 1.0 вам больше не нужно вводить
IHttpContextAccessor
класс расширения. Он сразу же доступен вIUrlHelper
форматеurlhelper.ActionContext.HttpContext.Request
. Затем вы должны создать класс расширения, следуя той же идее, но более простой, поскольку не будет задействована инъекция.public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = url.ActionContext.HttpContext.Request.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); }
Оставив подробности о том, как его построить, вводя аксессуар на случай, если они кому-то пригодятся. Вам также может быть интересен абсолютный URL-адрес текущего запроса, и в этом случае посмотрите в конец ответа.
Вы можете изменить свой класс расширения, чтобы использовать
IHttpContextAccessor
интерфейс для полученияHttpContext
. Если у вас есть контекст, то вы можете получитьHttpRequest
экземпляр изHttpContext.Request
и использовать его свойствоScheme
,Host
, иProtocol
т.д. , как в:string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
Например, вы можете потребовать, чтобы ваш класс был настроен с HttpContextAccessor:
public static class UrlHelperExtensions { private static IHttpContextAccessor HttpContextAccessor; public static void Configure(IHttpContextAccessor httpContextAccessor) { HttpContextAccessor = httpContextAccessor; } public static string AbsoluteAction( this IUrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = HttpContextAccessor.HttpContext.Request.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); } .... }
Это то, что вы можете сделать в своем
Startup
классе (файл Startup.cs):public void Configure(IApplicationBuilder app) { ... var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); UrlHelperExtensions.Configure(httpContextAccessor); ... }
Вероятно, вы могли бы придумать разные способы получения
IHttpContextAccessor
в своем классе расширения, но если вы хотите сохранить свои методы как методы расширения, в конце вам нужно будет ввестиIHttpContextAccessor
в свой статический класс. (В противном случае вам понадобится вIHttpContext
качестве аргумента при каждом вызове)Просто получаю absoluteUri текущего запроса
Если вы просто хотите получить абсолютный uri текущего запроса, вы можете использовать методы расширения
GetDisplayUrl
илиGetEncodedUrl
изUriHelper
класса. (Который отличается от помощника Ur L )Чтобы их использовать:
Microsoft.AspNet.Http.Extensions
.HttpContext
экземпляр. Он уже доступен в некоторых классах (например, в представлениях бритвы), но в других вам может потребоваться ввести,IHttpContextAccessor
как описано выше.this.Context.Request.GetDisplayUrl()
Альтернативой этим методам было бы вручную создать абсолютный uri, используя значения в
HttpContext.Request
объекте (аналогично тому, что делает RequireHttpsAttribute ):var absoluteUri = string.Concat( request.Scheme, "://", request.Host.ToUriComponent(), request.PathBase.ToUriComponent(), request.Path.ToUriComponent(), request.QueryString.ToUriComponent());
источник
UriHelper
ссылка мертва.@using Microsoft.AspNet.Http.Extensions
в представление Index.cshtml и смог использовать эти расширения, как в@Context.Request.GetDisplayUrl()
Для ASP.NET Core 1.0 и более поздних версий
/// <summary> /// <see cref="IUrlHelper"/> extension methods. /// </summary> public static class UrlHelperExtensions { /// <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 IUrlHelper url, string actionName, string controllerName, object routeValues = null) { return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } /// <summary> /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a /// virtual (relative) path to an application absolute path. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="contentPath">The content path.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteContent( this IUrlHelper url, string contentPath) { HttpRequest request = url.ActionContext.HttpContext.Request; return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString(); } /// <summary> /// Generates a fully qualified URL to the specified route by using the route name and route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="routeName">Name of the route.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteRouteUrl( this IUrlHelper url, string routeName, object routeValues = null) { return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } }
Бонусный совет
Вы не можете напрямую зарегистрировать объект
IUrlHelper
в контейнере DI. Для разрешения экземпляраIUrlHelper
требуется использовать клавишиIUrlHelperFactory
иIActionContextAccessor
. Однако вы можете сделать следующее в качестве ярлыка:Журнал невыполненных работ ASP.NET Core
ОБНОВЛЕНИЕ : это не сделает ASP.NET Core 5
Есть признаки того, что вы сможете использовать
LinkGenerator
для создания абсолютных URL без необходимости указыватьHttpContext
(это был самый большой недостатокLinkGenerator
и почему,IUrlHelper
хотя более сложную настройку с использованием решения ниже было проще использовать) См. "Упростить настройку хост / схема для абсолютных URL с LinkGenerator " .источник
string url = string.Concat(this.Request.Scheme, "://", this.Request.Host, this.Request.Path, this.Request.QueryString);
Для этого не нужно создавать метод расширения
@Url.Action("Action", "Controller", values: null);
Action
- Название акцииController
- Имя контроллераvalues
- Объект, содержащий значения маршрута: параметры GETЕсть также множество других перегрузок, которые
Url.Action
вы можете использовать для создания ссылок.источник
this.Context.Request.Scheme
. Это только часть протокола и домена URL-адреса?this.Context.Request.Schema
возвращает протокол, который использовался для запроса. Будетhttp
илиhttps
. Вот документы, но на самом деле они не объясняют, что означает схема.Если вам просто нужен Uri для метода с аннотацией маршрута, у меня сработало следующее.
Шаги
Получить относительный URL
Отметив имя маршрута целевого действия, получите относительный URL-адрес, используя свойство URL-адреса контроллера, как показано ниже:
var routeUrl = Url.RouteUrl("*Route Name Here*", new { *Route parameters here* });
Создать абсолютный URL
var absUrl = string.Format("{0}://{1}{2}", Request.Scheme, Request.Host, routeUrl);
Создать новый Uri
var uri = new Uri(absUrl, UriKind.Absolute)
пример
[Produces("application/json")] [Route("api/Children")] public class ChildrenController : Controller { private readonly ApplicationDbContext _context; public ChildrenController(ApplicationDbContext context) { _context = context; } // GET: api/Children [HttpGet] public IEnumerable<Child> GetChild() { return _context.Child; } [HttpGet("uris")] public IEnumerable<Uri> GetChildUris() { return from c in _context.Child select new Uri( $"{Request.Scheme}://{Request.Host}{Url.RouteUrl("GetChildRoute", new { id = c.ChildId })}", UriKind.Absolute); } // GET: api/Children/5 [HttpGet("{id}", Name = "GetChildRoute")] public IActionResult GetChild([FromRoute] int id) { if (!ModelState.IsValid) { return HttpBadRequest(ModelState); } Child child = _context.Child.Single(m => m.ChildId == id); if (child == null) { return HttpNotFound(); } return Ok(child); } }
источник
Это вариант ответа Мухаммада Рехана Саида , в котором класс паразитически присоединяется к существующему основному классу MVC .net с тем же именем, так что все просто работает.
namespace Microsoft.AspNetCore.Mvc { /// <summary> /// <see cref="IUrlHelper"/> extension methods. /// </summary> public static partial class UrlHelperExtensions { /// <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 IUrlHelper url, string actionName, string controllerName, object routeValues = null) { return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } /// <summary> /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a /// virtual (relative) path to an application absolute path. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="contentPath">The content path.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteContent( this IUrlHelper url, string contentPath) { HttpRequest request = url.ActionContext.HttpContext.Request; return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString(); } /// <summary> /// Generates a fully qualified URL to the specified route by using the route name and route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="routeName">Name of the route.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteRouteUrl( this IUrlHelper url, string routeName, object routeValues = null) { return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme); } } }
источник
Я только что обнаружил, что это можно сделать с помощью этого вызова:
Url.Action(new UrlActionContext { Protocol = Request.Scheme, Host = Request.Host.Value, Action = "Action" })
Это будет поддерживать схему, хост, порт, все.
источник
В новом проекте ASP.Net 5 MVC в действии контроллера вы все еще можете выполнять,
this.Context
иthis.Context.Request
похоже, что в запросе больше нет свойства Url, но все дочерние свойства (схема, хост и т.д.) находятся непосредственно в объекте запроса.public IActionResult About() { ViewBag.Message = "Your application description page."; var schema = this.Context.Request.Scheme; return View(); }
Скорее всего, вы хотите использовать this.Context или внедрить свойство - это еще один разговор. Внедрение зависимостей в ASP.NET vNext
источник
Если вы просто хотите преобразовать относительный путь с дополнительными параметрами, я создал метод расширения для IHttpContextAccessor
public static string AbsoluteUrl(this IHttpContextAccessor httpContextAccessor, string relativeUrl, object parameters = null) { var request = httpContextAccessor.HttpContext.Request; var url = new Uri(new Uri($"{request.Scheme}://{request.Host.Value}"), relativeUrl).ToString(); if (parameters != null) { url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, ToDictionary(parameters)); } return url; } private static Dictionary<string, string> ToDictionary(object obj) { var json = JsonConvert.SerializeObject(obj); return JsonConvert.DeserializeObject<Dictionary<string, string>>(json); }
Затем вы можете вызвать метод из своей службы / представления, используя введенный IHttpContextAccessor
var callbackUrl = _httpContextAccessor.AbsoluteUrl("/Identity/Account/ConfirmEmail", new { userId = applicationUser.Id, code });
источник
Вы можете получить такой URL-адрес:
Request.Headers["Referer"]
Объяснение
Request.UrlReferer
Будет бросать ,System.UriFormatException
если реферер HTTP заголовок неправильный формат (что может произойти , так как это обычно не под вашим контролем).Что касается использования
Request.ServerVariables
, согласно MSDN :Request.Headers Свойство
Получает коллекцию заголовков HTTP.
Думаю, я не понимаю, почему вы предпочли бы
Request.ServerVariables
overRequest.Headers
, поскольку онRequest.ServerVariables
содержит все переменные среды, а также заголовки, где Request.Headers - гораздо более короткий список, который содержит только заголовки.Поэтому лучшее решение - использовать
Request.Headers
коллекцию для непосредственного чтения значения. Обратите внимание на предупреждения Microsoft о кодировке значения HTML, если вы собираетесь отображать его в форме.источник