ASP.NET MVC의 모델에서 UrlHelper 호출


159

ASP.NET MVC의 모델에서 일부 URL을 생성해야합니다. URL을 생성하기 위해 경로를 사용하는 UrlHelper.Action ()과 같은 것을 호출하고 싶습니다. 호스트 이름, 구성표 등과 같은 일반적인 공백을 채우는 것은 중요하지 않습니다.

내가 요청할 수있는 방법이 있습니까? UrlHelper를 구성하는 방법이 있습니까?


1
나는 이것에 대해 스스로 생각하고 있었지만 Url.Action이 상대 URL을 생성한다는 것을 알고 있습니다. 그것이 당신이 원하는 것인지 확인하십시오.
Vivian River

답변:


277

유용한 팁 : 모든 ASP.NET 응용 프로그램에서 현재 HttpContext에 대한 참조를 얻을 수 있습니다.

HttpContext.Current

System.Web에서 파생됩니다. 따라서 다음은 ASP.NET MVC 응용 프로그램의 어느 곳에서나 작동합니다.

UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info

예:

public class MyModel
{
    public int ID { get; private set; }
    public string Link
    {
        get
        {
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
            return url.Action("ViewAction", "MyModelController", new { id = this.ID });
        }
    }

    public MyModel(int id)
    {
        this.ID = id;
    }
}

Link생성 된 MyModel 객체 에서 속성을 호출하면 Global.asax의 라우팅을 기반으로 모델을 볼 수있는 유효한 Url이 반환됩니다.


HttpContext.Current.Request.RequestContext가 있습니까? HttpContext.Current.Request에 RequestContext가없는 것 같습니다.
pupeno

1
이상하다. 방금이 솔루션을 테스트했으며 완벽하게 작동합니다. ASP.NET MVC 2 Preview 2를 실행하고 있지만 모든 버전에서 작동한다고 생각합니다. 왜 작동하지 않는지 잘 모르겠습니다. MVC 프로젝트 외부에서 클래스를 작성하고 있습니까? 또한이되어 있는지 확인합니다 using모두 System.WebSystem.Web.Mvc
오마르

ASP.NET MVC 1 프로젝트에 있는데 누락 된 사용법에 대해 생각했지만 둘 다 있습니다.
pupeno

왜 보이지 않는지 잘 모르겠습니다. 다른 사람이 ASP.NET MVC 1에 존재하지 않는다는 것을 확인할 수 있다면 좋을 것입니다. VS2010 및 MVC 2가 설치된 시스템이 하나만 있습니다. 관심이 있으시면
Omar

6
Request.RequestContex는 .NET4 +에서 지원됨
h--n

64

나는 Omar의 대답을 좋아하지만 그것은 나를 위해 작동하지 않습니다. 기록을 위해 이것은 현재 사용중인 솔루션입니다.

var httpContext = HttpContext.Current;

if (httpContext == null) {
  var request = new HttpRequest("/", "http://example.com", "");
  var response = new HttpResponse(new StringWriter());
  httpContext = new HttpContext(request, response);
}

var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);

return new UrlHelper(requestContext);

내 사이트의 URL이 포함되어 있습니다. 거기서 제거했습니다.
pupeno

4
UrlHelper 클래스가 요청 컨텍스트 (및 HTTP 컨텍스트)에 의존한다는 것을 고려하면 해당 컨텍스트 오브젝트를 수동으로 구성하면 예기치 않은 결과가 발생할 수 있습니다. HttpContext.Current가 null이고이 방법을 사용하는 경우주의해서 진행합니다.
Sean

4
이 답변에 유의하십시오-희미한 RequestContext는 항상 빈 문자열을 반환하는 UrlHelper를 생성합니다.
gknicker

47

UrlHelper는 다음을 사용하여 Controller 조치 내에서 구성 할 수 있습니다.

 var url = new UrlHelper(this.ControllerContext.RequestContext);
 url.Action(...);

컨트롤러 외부에서 RouteTable.Routes RouteData에서 RequestContext를 만들어 UrlHelper를 구성 할 수 있습니다.

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));

(Brian의 답변을 바탕으로 사소한 코드 수정이 추가되었습니다.)


2
그러나 모델에는 컨트롤러가 없습니다.
pupeno

죄송합니다. 코드가 어디에서 실행되고 있는지 확실하지 않았습니다. 한번 보자 ...
Nathan Taylor

2
새로운 요청 컨텍스트를 생성 할 필요가 없습니다 :var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7

좋은 @ bradlis7. MVC 5입니까?
Nathan Taylor

1
때문에,하지 작업을 수행 this.ControllerContext.RequestContextA는 HttpRequestContext, 그리고 생성자 UrlHelper예상하는 RequestContext. 두 클래스는 서로 관련이 없습니다.
Florian Winter

8

예, 인스턴스화 할 수 있습니다. 당신은 다음과 같은 것을 할 수 있습니다 :

var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
   new RequestContext(ctx,
   RouteTable.Routes.GetRouteData(ctx));

RouteTable.Routes정적 속성이므로 여기서 확인해야합니다. 얻을 HttpContextBase참조를 HttpContextWrapper참조 소요 HttpContext, 그리고 HttpContext그을 제공합니다.


매우 가깝지만 작동하지 않습니다. 아래 답변을 참조하십시오.
Nathan Taylor

3

다른 모든 대답을 시도한 후에 나는 결국

$"/api/Things/Action/{id}"

증오자는 ¯ \ _ (ツ) _ / ¯


0

페이지 내에서 (컨트롤러 외부에서) 비슷한 것을하려고했습니다.

UrlHelper를 사용하면 Pablos가 대답하는 것처럼 쉽게 구성 할 수 없었지만 동일한 작업을 효과적으로 수행하는 오래된 트릭을 기억했습니다.

string ResolveUrl(string pathWithTilde)

-30

나는 당신이 찾고있는 것이 이것이라고 생각합니다.

Url.Action("ActionName", "ControllerName");
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.