使用 ASP.NET Core 获取绝对 URL
Getting absolute URLs using ASP.NET Core
在 MVC 5 中,我有以下扩展方法来生成绝对 URLs,而不是相对的:
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 上吗?这是更好的方法吗?
在控制器操作中的新 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 或注入 属性 是另一个对话。
Dependency Injection in ASP.NET vNext
在 RC2 和 1.0 之后,您不再需要向扩展 class 注入 IHttpContextAccessor
。它在 IUrlHelper
到 urlhelper.ActionContext.HttpContext.Request
中立即可用。然后,您将按照相同的想法创建一个扩展 class,但更简单,因为不会涉及注入。
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 感兴趣,在这种情况下请查看答案的末尾。
您可以修改您的扩展 class 以使用 HttpContext.Request
中的 IHttpContextAccessor
interface to get the HttpContext
. Once you have the context, then you can get the HttpRequest
实例并使用其属性 Scheme
、Host
、Protocol
等,如:
string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
例如,您可能需要为 class 配置 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
class(Startup.cs 文件)上执行以下操作:
public void Configure(IApplicationBuilder app)
{
...
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
UrlHelperExtensions.Configure(httpContextAccessor);
...
}
您可能会想出不同的方法在您的扩展 class 中获取 IHttpContextAccessor
,但是如果您希望最终将您的方法保留为扩展方法,您将需要注入IHttpContextAccessor
变成你的静态 class。 (否则您将需要 IHttpContext
作为每次调用的参数)
只是获取当前请求的absoluteUri
如果只想获取当前请求的绝对uri,可以使用UriHelper
class中的扩展方法GetDisplayUrl
或GetEncodedUrl
。 (与 UrLHelper 不同)
GetDisplayUrl. Returns the combined components of the request URL in a fully un-escaped form (except for the QueryString) suitable only
for display. This format should not be used in HTTP headers or other
HTTP operations.
GetEncodedUrl. Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers and other
HTTP operations.
为了使用它们:
- 包括命名空间
Microsoft.AspNet.Http.Extensions
。
- 获取
HttpContext
实例。它已经在一些 classes 中可用(如剃刀视图),但在其他人中你可能需要注入一个 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());
如果您只是想要一个具有路由注释的方法的 Uri,以下方法对我有用。
步骤
获取相对 URL
注意目标动作的Route名称,使用controller的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);
}
}
你可以这样得到url:
Request.Headers["Referer"]
说明
如果引用 HTTP header 格式错误(这可能发生,因为它通常不受您的控制),Request.UrlReferer
将抛出 System.UriFormatException
。
至于使用Request.ServerVariables
,per MSDN:
Request.ServerVariables Collection
The ServerVariables collection retrieves the values of predetermined environment variables and request header information.
Request.Headers 属性
获取 collection 的 HTTP headers。
我想我不明白为什么您更喜欢 Request.ServerVariables
而不是 Request.Headers
,因为 Request.ServerVariables
包含所有环境变量以及 header s,其中 Request.Headers 是一个更短的列表,仅包含 headers.
所以最好的解决办法是使用Request.Headers
collection直接读取值。不过,如果要在表单上显示值,请注意 Microsoft 关于 HTML 对值进行编码的警告。
对于 ASP.NET Core 1.0 Onwards
/// <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);
}
}
奖金提示
您不能直接在 DI 容器中注册一个 IUrlHelper
。解析 IUrlHelper
的实例需要您使用 IUrlHelperFactory
和 IActionContextAccessor
。但是,您可以执行以下操作作为快捷方式:
services
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddScoped<IUrlHelper>(x => x
.GetRequiredService<IUrlHelperFactory>()
.GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));
ASP.NET 核心积压
更新:这不会使 ASP.NET Core 5
有迹象表明,您可以使用 LinkGenerator
创建绝对 URL,而无需提供 HttpContext
(这是 LinkGenerator
的最大缺点,为什么 IUrlHelper
尽管使用下面的解决方案设置起来更复杂但更易于使用)参见 "Make it easy to configure a host/scheme for absolute URLs with LinkGenerator"。
这是 Muhammad Rehan Saeed 的 anwser 的变体,class 寄生地附加到同名的现有 .net 核心 MVC class,因此一切都只是有效。
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);
}
}
}
如果您只想转换带有可选参数的相对路径,我为 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
从您的 service/view 调用方法
var callbackUrl = _httpContextAccessor.AbsoluteUrl("/Identity/Account/ConfirmEmail", new { userId = applicationUser.Id, code });
您不需要为此创建扩展方法
@Url.Action("Action", "Controller", values: null);
Action
- 动作名称
Controller
- 控制器名称
values
- 包含路由值的对象:又名 GET 参数
还有 lots of other overloads to Url.Action
可以用来生成链接。
我刚刚发现你可以通过这个电话来做到这一点:
Url.Action(new UrlActionContext
{
Protocol = Request.Scheme,
Host = Request.Host.Value,
Action = "Action"
})
这将维护方案、主机、端口等所有内容。
ASP.NET Core 3.0 及更高版本已经为 IUrlHelper
提供了 ActionLink
and PageLink
扩展方法,其目的是分别为操作和页面生成绝对 URL。
在控制器操作或页面中,可以通过 Url
属性:
访问 IUrlHelper
实例
public IActionResult Index()
{
string absoluteActionUrl = Url.ActionLink("ActionName", "ControllerName");
string absolutePageUrl = Url.PageLink("/Page");
...
}
在 MVC 5 中,我有以下扩展方法来生成绝对 URLs,而不是相对的:
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 上吗?这是更好的方法吗?
在控制器操作中的新 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 或注入 属性 是另一个对话。 Dependency Injection in ASP.NET vNext
在 RC2 和 1.0 之后,您不再需要向扩展 class 注入 IHttpContextAccessor
。它在 IUrlHelper
到 urlhelper.ActionContext.HttpContext.Request
中立即可用。然后,您将按照相同的想法创建一个扩展 class,但更简单,因为不会涉及注入。
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 感兴趣,在这种情况下请查看答案的末尾。
您可以修改您的扩展 class 以使用 HttpContext.Request
中的 IHttpContextAccessor
interface to get the HttpContext
. Once you have the context, then you can get the HttpRequest
实例并使用其属性 Scheme
、Host
、Protocol
等,如:
string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
例如,您可能需要为 class 配置 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
class(Startup.cs 文件)上执行以下操作:
public void Configure(IApplicationBuilder app)
{
...
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
UrlHelperExtensions.Configure(httpContextAccessor);
...
}
您可能会想出不同的方法在您的扩展 class 中获取 IHttpContextAccessor
,但是如果您希望最终将您的方法保留为扩展方法,您将需要注入IHttpContextAccessor
变成你的静态 class。 (否则您将需要 IHttpContext
作为每次调用的参数)
只是获取当前请求的absoluteUri
如果只想获取当前请求的绝对uri,可以使用UriHelper
class中的扩展方法GetDisplayUrl
或GetEncodedUrl
。 (与 UrLHelper 不同)
GetDisplayUrl. Returns the combined components of the request URL in a fully un-escaped form (except for the QueryString) suitable only for display. This format should not be used in HTTP headers or other HTTP operations.
GetEncodedUrl. Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers and other HTTP operations.
为了使用它们:
- 包括命名空间
Microsoft.AspNet.Http.Extensions
。 - 获取
HttpContext
实例。它已经在一些 classes 中可用(如剃刀视图),但在其他人中你可能需要注入一个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());
如果您只是想要一个具有路由注释的方法的 Uri,以下方法对我有用。
步骤
获取相对 URL
注意目标动作的Route名称,使用controller的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);
}
}
你可以这样得到url:
Request.Headers["Referer"]
说明
如果引用 HTTP header 格式错误(这可能发生,因为它通常不受您的控制),Request.UrlReferer
将抛出 System.UriFormatException
。
至于使用Request.ServerVariables
,per MSDN:
Request.ServerVariables Collection
The ServerVariables collection retrieves the values of predetermined environment variables and request header information.
Request.Headers 属性
获取 collection 的 HTTP headers。
我想我不明白为什么您更喜欢 Request.ServerVariables
而不是 Request.Headers
,因为 Request.ServerVariables
包含所有环境变量以及 header s,其中 Request.Headers 是一个更短的列表,仅包含 headers.
所以最好的解决办法是使用Request.Headers
collection直接读取值。不过,如果要在表单上显示值,请注意 Microsoft 关于 HTML 对值进行编码的警告。
对于 ASP.NET Core 1.0 Onwards
/// <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);
}
}
奖金提示
您不能直接在 DI 容器中注册一个 IUrlHelper
。解析 IUrlHelper
的实例需要您使用 IUrlHelperFactory
和 IActionContextAccessor
。但是,您可以执行以下操作作为快捷方式:
services
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddScoped<IUrlHelper>(x => x
.GetRequiredService<IUrlHelperFactory>()
.GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));
ASP.NET 核心积压
更新:这不会使 ASP.NET Core 5
有迹象表明,您可以使用 LinkGenerator
创建绝对 URL,而无需提供 HttpContext
(这是 LinkGenerator
的最大缺点,为什么 IUrlHelper
尽管使用下面的解决方案设置起来更复杂但更易于使用)参见 "Make it easy to configure a host/scheme for absolute URLs with LinkGenerator"。
这是 Muhammad Rehan Saeed 的 anwser 的变体,class 寄生地附加到同名的现有 .net 核心 MVC class,因此一切都只是有效。
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);
}
}
}
如果您只想转换带有可选参数的相对路径,我为 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
从您的 service/view 调用方法var callbackUrl = _httpContextAccessor.AbsoluteUrl("/Identity/Account/ConfirmEmail", new { userId = applicationUser.Id, code });
您不需要为此创建扩展方法
@Url.Action("Action", "Controller", values: null);
Action
- 动作名称Controller
- 控制器名称values
- 包含路由值的对象:又名 GET 参数
还有 lots of other overloads to Url.Action
可以用来生成链接。
我刚刚发现你可以通过这个电话来做到这一点:
Url.Action(new UrlActionContext
{
Protocol = Request.Scheme,
Host = Request.Host.Value,
Action = "Action"
})
这将维护方案、主机、端口等所有内容。
ASP.NET Core 3.0 及更高版本已经为 IUrlHelper
提供了 ActionLink
and PageLink
扩展方法,其目的是分别为操作和页面生成绝对 URL。
在控制器操作或页面中,可以通过 Url
属性:
IUrlHelper
实例
public IActionResult Index()
{
string absoluteActionUrl = Url.ActionLink("ActionName", "ControllerName");
string absolutePageUrl = Url.PageLink("/Page");
...
}