在ASP.NET MVC中的模型中调用UrlHelper


159

我需要在ASP.NET MVC中的模型中生成一些URL。我想调用UrlHelper.Action()之类的东西,它使用路由生成URL。我不介意填写通常的空白,例如主机名,方案等。

有什么我可以调用的方法吗?有没有办法构造一个UrlHelper?


1
我本人也在考虑这一点,但请注意,Url.Action将生成一个相对URL。确保这就是您想要的。
维维安河

Answers:


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对象上调用属性将返回有效的URL,以根据Global.asax中的路由查看模型。


您确定存在HttpContext.Current.Request.RequestContext吗?HttpContext.Current.Request似乎没有RequestContext。
pupeno 2010年

1
太奇怪了。我刚刚测试了此解决方案,它运行良好。我正在运行ASP.NET MVC 2 Preview 2,但我认为这适用于所有版本。不知道为什么它对您不起作用。您是在MVC项目之外创建类吗?另外,还要确保有using两个System.WebSystem.Web.Mvc
奥马尔

我在一个ASP.NET MVC 1项目上,我曾想过缺少使用方法,但我两个都有。
pupeno 2010年

不太确定为什么不显示。如果其他人可以确认这在ASP.NET MVC 1中不存在,那就太好了。我只有一台装有VS2010和MVC 2的计算机。如果您有兴趣,请访问MVC RC 2 haacked.com/archive/2009/12/16/aspnetmvc-2-rc.aspx
Omar

6
需要注意的是Request.RequestContex在.NET4支持+
N - ^ h

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,并且您使用此方法,请谨慎行事。
肖恩

4
当心这个答案-模糊的RequestContext导致UrlHelper始终返回空字符串。
gknicker's

47

可以从Controller动作中使用以下内容构造UrlHelper:

 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 2010年

好的,很抱歉,我不确定代码的确切执行位置。让我看一下...
Nathan Taylor

2
无需创建新的请求上下文:var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7 2015年

尼斯@ bradlis7。那是MVC 5吗?
内森·泰勒

1
不起作用,因为this.ControllerContext.RequestContextHttpRequestContext,并且的构造函数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参考HttpContextHttpContext提供参考。


尽管非常接近,但这是行不通的。请参阅下面的答案。
内森·泰勒

3

在尝试了所有其他答案之后,我最终得到了

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

仇恨者会讨厌¯\ _(ツ)_ /¯


0

我试图从页面内(控制器外部)执行类似操作。

UrlHelper不允许我像Pablos回答那样容易地构造它,但是后来我想起了有效做同样事情的老技巧:

string ResolveUrl(string pathWithTilde)

-30

我认为您正在寻找的是:

Url.Action("ActionName", "ControllerName");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.