在MVC 5中,我有以下扩展方法来生成绝对URL,而不是相对的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?这会是一种更好的方法吗?
答案 0 :(得分:60)
在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
。获得上下文后,您就可以从HttpContext.Request
获取HttpRequest
实例并使用其属性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
作为每个电话的参数)
获取当前请求的绝对值
如果您只想获取当前请求的绝对值,可以使用UriHelper
类中的扩展方法GetDisplayUrl
或GetEncodedUrl
。 (这与Ur L Helper不同)
<强> GetDisplayUrl 即可。以完全未转义的形式(QueryString除外)仅返回请求URL的组合组件 用于显示。不应在HTTP标头或其他标头中使用此格式 HTTP操作。
<强> GetEncodedUrl 即可。以完全转义的形式返回请求URL的组合组件,适用于HTTP标头和其他标头 HTTP操作。
为了使用它们:
Microsoft.AspNet.Http.Extensions
。 HttpContext
个实例。它已经在某些类(如剃刀视图)中可用,但在其他类中,您可能需要注入IHttpContextAccessor
,如上所述。 this.Context.Request.GetDisplayUrl()
这些方法的替代方法是使用HttpContext.Request
对象中的值手动制作绝对uri(类似于RequireHttpsAttribute所做的):
var absoluteUri = string.Concat(
request.Scheme,
"://",
request.Host.ToUriComponent(),
request.PathBase.ToUriComponent(),
request.Path.ToUriComponent(),
request.QueryString.ToUriComponent());
答案 1 :(得分:33)
您可以使用以下代码或使用Django docs NuGet包或查看Boxed.AspNetCore GitHub存储库中的代码。
IUrlHelper
您无法在DI容器中直接注册IUrlHelper
。解析IUrlHelperFactory
的实例需要您使用IActionContextAccessor
和services
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddScoped<IUrlHelper>(x => x
.GetRequiredService<IUrlHelperFactory>()
.GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));
。但是,您可以执行以下操作作为快捷方式:
angular js
答案 2 :(得分:10)
如果您只是想要一个具有路径注释的方法的Uri,以下内容对我有效。
注意目标操作的路由名称,使用控制器的URL属性获取相对URL,如下所示:
var routeUrl = Url.RouteUrl("*Route Name Here*", new { *Route parameters here* });
var absUrl = string.Format("{0}://{1}{2}", Request.Scheme,
Request.Host, routeUrl);
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);
}
}
答案 3 :(得分:4)
这是anwser Muhammad Rehan Saeed的变体,该类被寄生地附加到同名的现有.net核心MVC类,因此一切正常。
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);
}
}
}
答案 4 :(得分:4)
我刚刚发现您可以通过以下电话进行操作:
Url.Action(new UrlActionContext
{
Protocol = Request.Scheme,
Host = Request.Host.Value,
Action = "Action"
})
这将维护方案,主机,端口以及所有内容。
答案 5 :(得分:3)
在控制器操作中的新ASP.Net 5 MVC项目中,您仍然可以b
和this.Context
看起来在请求中不再有Url属性,而是子属性(模式) ,主机等)都直接在请求对象上。
this.Context.Request
你想要使用this.Context还是注入属性是另一个对话。 Dependency Injection in ASP.NET vNext
答案 6 :(得分:2)
你可以得到这样的网址:
Request.Headers["Referer"]
<强>解释强>
如果引用HTTP标头格式不正确,Request.UrlReferer
将抛出System.UriFormatException
(这可能发生,因为它通常不受您的控制)。
至于使用Request.ServerVariables
,per MSDN:
Request.ServerVariables Collection
ServerVariables集合检索预定环境变量的值并请求标头信息。
Request.Headers Property
获取HTTP标头的集合。
我想我不明白为什么你更喜欢Request.ServerVariables
而不是Request.Headers
,因为Request.ServerVariables
包含所有环境变量以及标题,其中Request.Headers是一个只包含标题的更短的列表。
所以最好的解决方案是使用Request.Headers
集合直接读取值。如果您打算在表单上显示该值,请注意Microsoft关于HTML编码值的警告。
答案 7 :(得分:2)
您无需为此创建扩展方法
@Url.Action("Action", "Controller", null, this.Context.Request.Scheme);
答案 8 :(得分:0)
如果只想转换带有可选参数的相对路径,我为 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 });