如何在ASP.NET MVC中找到操作的绝对URL?


239

我需要做这样的事情:

<script type="text/javascript">
    token_url = "http://example.com/your_token_url";
</script>

我正在使用MVC的Beta版,但无法弄清楚如何获取操作的绝对网址。我想做这样的事情:

<%= Url.AbsoluteAction("Action","Controller")) %>

是否有帮助程序或Page方法?

Answers:


480

单击此处以获取更多信息,但是从本质上讲,不需要扩展方法。它已经烤熟了,只是不是以一种非常直观的方式。

Url.Action("Action", null, null, Request.Url.Scheme);

6
有趣的是,如果您指定协议,则该URL是绝对的
Casebash 2010年

24
这个答案是更好的答案,通过这种方式Resharper仍然可以验证Action和Controller是否存在。我建议使用Request.Url.Scheme代替http,这样就同时支持http和https。
Pbirkoff 2012年

2
@Pbirkoff,同意这是最好的答案,但是您可能想知道,您可以为ReSharper注释自己的方法,以知道参数表示动作/控制器。这样,R#仍然可以很好地验证您提供的字符串。
德鲁·诺阿克斯

3
一个小的改进可能是将“ http”替换为,Request.Url.Scheme因此,如果您使用HTTPS,则生成的URL也将使用HTTPS。
Erik Schierboom

1
这也适用Html.ActionLink(采用某种协议的任何方法,例如MVC 4中的最后2种)
Chris

74

扩展UrlHelper

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this UrlHelper url, string action, string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

然后这样称呼它

<%= Url.AbsoluteAction("Dashboard", "Account")%>

编辑-整形注解

关于已接受答案的最受好评的评论是,This answer is the better one, this way Resharper can still validate that the Action and Controller exists.因此,这里有一个示例,您可以了解如何获得相同的行为。

using JetBrains.Annotations

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(
            this UrlHelper url,
            [AspMvcAction]
            string action,
            [AspMvcController]
            string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

支持信息:


3
我还将为此解决方案添加可选参数。这应该涵盖所有情况。
Eugeniu Torica,2009年

非常好!我使用了这段代码,但是我做了唯一的参数relativeUrl,以便调用者可以使用他们喜欢的任何Url方法(路由器值等)来创建它,而您的方法只负责使其相对。所以我的是:AbsoluteUrl(此UrlHelper url,字符串relativeUrl)。
罗伯·肯特


21

以@Charlino的答案为指导,我想到了这一点。

用于UrlHelperASP.NET MVC文档显示,如果传入了主机名和协议,则Url.Action将返回完全限定的Url。我创建了这些助手来强制提供主机名和协议。多个重载反映了Url.Action的重载:

using System.Web.Routing;

namespace System.Web.Mvc {
    public static class HtmlExtensions {

        public static string AbsoluteAction(this UrlHelper url, string actionName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, new RouteValueDictionary(routeValues), 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, routeValues, requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, routeValues, requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, object routeValues, 
                                            string protocol) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), protocol, null);
        }

    }
}

4
Thx代码对我有很大帮助,但是这种解决方案通常在开发过程中会出现问题。如果站点托管在特定端口上,则端口信息包含在requestUrl.Authority中,例如localhost:4423。由于某种原因,Action方法将再次追加端口。因此,这可能是操作方法中的错误,或者您不应该在此处提供端口。但是,请求中哪个可用属性是正确的(DnsSafeHost或Host)?好了,解决方案非常简单:只需提供null,然后Action方法将填充正确的值。
ntziolis 2010年

我已经更新了答案,以纳入@ntziolis的建议。
安德鲁·阿诺特

3

我不确定是否有内置方法可以执行此操作,但是您可以滚动自己的HtmlHelper方法。

类似于以下内容

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this HtmlHelper html, string actionUrl)
        {
            Uri requestUrl = html.ViewContext.HttpContext.Request.Url;

            string absoluteAction = string.Format("{0}://{1}{2}",
                                                  requestUrl.Scheme,
                                                  requestUrl.Authority,
                                                  actionUrl);

            return absoluteAction;
        }
    }
}

然后这样称呼它

<%= Html.AbsoluteAction(Url.Action("Dashboard", "Account"))%> »

查尔斯·HTH


2

带参数的完整答案是:

var url = Url.Action("ActionName", "ControllerName", new { id = "arg_value" }, Request.Url.Scheme);

这将产生一个绝对的URL


1

结果相同,但更简洁(没有字符串连接/格式化):

public static Uri GetBaseUrl(this UrlHelper url)
{
    Uri contextUri = new Uri(url.RequestContext.HttpContext.Request.Url, url.RequestContext.HttpContext.Request.RawUrl);
    UriBuilder realmUri = new UriBuilder(contextUri) { Path = url.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
    return realmUri.Uri;
}

public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName)
{
    return new Uri(GetBaseUrl(url), url.Action(actionName, controllerName)).AbsoluteUri;
}

0

也许这(?):

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>

0

env:dotnet核心版本1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
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.