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에 간단하게 추가되는 환경 변수 여야합니까? 이것이 더 나은 접근 방식일까요?
답변
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 Helper 와 다른 점 )
GetDisplayUrl . 표시 전용으로 적합한 완전히 이스케이프되지 않은 형식 (QueryString 제외)으로 요청 URL의 결합 된 구성 요소를 반환합니다. 이 형식은 HTTP 헤더 또는 기타 HTTP 작업에 사용해서는 안됩니다.
GetEncodedUrl . HTTP 헤더 및 기타 HTTP 작업에 사용하기에 적합한 완전히 이스케이프 된 형식으로 요청 URL의 결합 된 구성 요소를 반환합니다.
그것들을 사용하려면 :
- 네임 스페이스를 포함합니다
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());
답변
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
. 그러나 바로 가기로 다음을 수행 할 수 있습니다.
services
.AddSingleton<IActionContextAccessor, ActionContextAccessor>()
.AddScoped<IUrlHelper>(x => x
.GetRequiredService<IUrlHelperFactory>()
.GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));
ASP.NET Core 백 로그
업데이트 : 이것은 ASP.NET Core 5를 만들지 않습니다.
LinkGenerator
제공 할 필요없이 절대 URL을 생성하는 데 사용할 수 있다는 표시가 있습니다 HttpContext
( 아래 솔루션을 사용하여 설정하는 것이 더 복잡했지만 사용하기가 더 쉬웠지만 LinkGenerator
이것이 가장 큰 단점이었던 이유 IUrlHelper
). “구성하기 쉽게 만들기 LinkGenerator를 사용하는 절대 URL에 대한 호스트 / 체계 “ .
답변
이를 위해 확장 메서드를 만들 필요가 없습니다.
@Url.Action("Action", "Controller", values: null);
Action
-액션의 이름Controller
-컨트롤러 이름values
-경로 값을 포함하는 객체 : 일명 GET 매개 변수
링크를 생성하는 데 사용할 수있는 다른 많은 오버로드Url.Action
도 있습니다.
답변
경로 주석이있는 메서드에 대한 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);
}
}
답변
이것은 Muhammad Rehan Saeed 의 anwser의 변형으로, 클래스가 동일한 이름의 기존 .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);
}
}
}
답변
이 전화로 할 수 있다는 것을 방금 발견했습니다.
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();
}
오히려 이것을 사용하든 원하지 않든 컨텍스트 또는 속성을 주입하는 것은 다른 대화입니다.
ASP.NET vNext의 종속성 주입