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

Mik*_*ock 233 asp.net-mvc

我需要做这样的事情:

<script type="text/javascript">
    token_url = "http://example.com/your_token_url";
</script>
Run Code Online (Sandbox Code Playgroud)

我正在使用MVC的Beta版本,但我无法弄清楚如何获取动作的绝对URL.我想做这样的事情:

<%= Url.AbsoluteAction("Action","Controller")) %>
Run Code Online (Sandbox Code Playgroud)

是否有帮助器或Page方法?

Ada*_*ton 470

单击此处获取更多信息,但实际上不需要扩展方法.它已经烘焙过,而不是以非常直观的方式.

Url.Action("Action", null, null, Request.Url.Scheme);
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是更好的,这样Resharper仍然可以验证Action和Controller是否存在.我建议使用Request.Url.Scheme而不是http,这样就支持http和https. (22认同)
  • 有趣,所以如果你指定协议,URL是绝对的 (6认同)
  • 一个小的改进可能是用'Request.Url.Scheme`替换**"http"**,这样如果你使用HTTPS,生成的url也将使用HTTPS. (3认同)
  • @Pbirkoff,同意这是最好的答案,但您可能想知道您可以为ReSharper注释自己的方法,以了解参数代表操作/控制器.这样,R#仍然可以验证您提供的字符串,因为它做得很好. (2认同)

Cha*_*ino 73

扩展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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后这样称呼它

<%= Url.AbsoluteAction("Dashboard", "Account")%>
Run Code Online (Sandbox Code Playgroud)

编辑 - 再生注释

对于已接受的答案,最受欢迎的评论是,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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

支持信息:

  • 我还会为此解决方案添加可选参数.这应涵盖所有情况. (3认同)
  • 我更喜欢这个答案,因为它使我的代码更具可读性. (2认同)

Rya*_*son 26

<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>
Run Code Online (Sandbox Code Playgroud)


Ral*_*ner 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);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 代码的Thx对我帮助很大,但是这个解决方案在开发过程中通常会出现问题.如果站点托管在特定端口上,则端口信息包含在*requestUrl.Authority*中,如*localhost:4423*.由于某种原因,Action方法再次附加端口.因此,这是Action Method中的一个错误,或者你不应该在这里提供端口.但请求中哪些可用的属性是正确的(DnsSafeHost或主机)?那么解决方案很简单:只需提供*null*,Action方法将填入正确的值. (4认同)

Das*_*ath 6

带参数的完整答案是:

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

这将产生一个绝对网址