首页 文章

获取ASP.NET MVC中的完整操作URL [重复]

提问于
浏览
351

这个问题在这里已有答案:

是否有内置的方法来获取操作的完整URL?

我正在寻找像 GetFullUrl("Action", "Controller") 这样会返回类似 http://www.fred.com/Controller/Action 的东西 .

我正在寻找这个的原因是为了避免在生成的自动电子邮件中硬编码URL,以便始终可以相对于站点的当前位置生成URL .

6 回答

  • 0

    Url.Action过载会将您所需的协议(例如http,https)作为参数 - 如果您指定了此协议,则会获得完全限定的URL .

    这是一个在动作方法中使用当前请求的协议的示例:

    var fullUrl = this.Url.Action("Edit", "Posts", new { id = 5 }, this.Request.Url.Scheme);
    

    HtmlHelper(@Html)也有一个ActionLink方法的重载,您可以在razor中使用它来创建一个锚元素,但它还需要hostName和fragment参数 . 所以我只想再次使用@ Url.Action:

    <span>
      Copy
      <a href='@Url.Action("About", "Home", null, Request.Url.Scheme)'>this link</a> 
      and post it anywhere on the internet!
    </span>
    
  • 534

    帕迪提到: if you use an overload of UrlHelper.Action() that explicitly specifies the protocol to use, the generated URL will be absolute and fully qualified instead of being relative.

    我写了一篇名为How to build absolute action URLs using the UrlHelper class的博客文章,其中我建议为了便于阅读而编写自定义扩展方法:

    /// <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 UrlHelper url,
        string actionName, string controllerName, object routeValues = null)
    {
        string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;
    
        return url.Action(actionName, controllerName, routeValues, scheme);
    }
    

    然后,您可以在视图中使用它:

    @Url.AbsoluteAction("Action", "Controller")
    
  • 0

    这可能只是我真的,非常挑剔,但我喜欢只定义一次常量 . 如果您使用上面定义的任何方法,您的动作常量将定义多次 .

    为避免这种情况,您可以执行以下操作:

    public class Url
        {
            public string LocalUrl { get; }
    
            public Url(string localUrl)
            {
                LocalUrl = localUrl;
            }
    
            public override string ToString()
            {
                return LocalUrl;
            }
        }
    
        public abstract class Controller
        {
            public Url RootAction => new Url(GetUrl());
    
            protected abstract string Root { get; }
    
            public Url BuildAction(string actionName)
            {
                var localUrl = GetUrl() + "/" + actionName;
                return new Url(localUrl);
            }
    
            private string GetUrl()
            {
                if (Root == "")
                {
                    return "";
                }
    
                return "/" + Root;
            }
    
            public override string ToString()
            {
                return GetUrl();
            }
        }
    

    然后创建你的控制器,例如DataController:

    public static readonly DataController Data = new DataController();
        public class DataController : Controller
        {
            public const string DogAction = "dog";
            public const string CatAction = "cat";
            public const string TurtleAction = "turtle";
    
            protected override string Root => "data";
    
            public Url Dog => BuildAction(DogAction);
            public Url Cat => BuildAction(CatAction);
            public Url Turtle => BuildAction(TurtleAction);
        }
    

    然后就像使用它:

    // GET: Data/Cat
        [ActionName(ControllerRoutes.DataController.CatAction)]
        public ActionResult Etisys()
        {
            return View();
        }
    

    从您的.cshtml(或任何代码)

    <ul>
        <li><a href="@ControllerRoutes.Data.Dog">Dog</a></li>
        <li><a href="@ControllerRoutes.Data.Cat">Cat</a></li>
    </ul>
    

    这肯定是更多的工作,但我很容易知道编译时验证在我身边 .

  • 0

    这就是你需要做的 .

    @Url.Action(action,controller, null, Request.Url.Scheme)
    
  • 128

    我遇到了这个问题,我的服务器在负载均衡器后面运行 . 负载均衡器正在终止SSL / TLS连接 . 然后它使用http将请求传递给Web服务器 .

    在Request.Url.Schema中使用Url.Action()方法,它一直在创建一个http url,在我的例子中,在自动电子邮件中创建一个链接(我的PenTester不喜欢) .

    我可能有一点作弊,但这正是我需要强制https网址:

    <a href="@Url.Action("Action", "Controller", new { id = Model.Id }, "https")">Click Here</a>
    

    我实际上使用web.config AppSetting所以我可以在本地调试时使用http,但所有测试和prod环境都使用转换来设置https值 .

  • 0

    这个问题是针对ASP .NET的,但我相信你们中的一些人会受益于系统无关的javascript,这在许多情况下是有益的 .

    UPDATE: 在上面的答案中很好地描述了在页面外部形成url的方法 .

    或者你可以做一个如下的oneliner:

    new UrlHelper(actionExecutingContext.RequestContext).Action(
        "SessionTimeout", "Home", 
        new {area = string.Empty}, 
        actionExecutingContext.Request.Url!= null? 
        actionExecutingContext.Request.Url.Scheme : "http"
    );
    

    来自过滤器或:

    new UrlHelper(this.Request.RequestContext).Action(
        "Details", 
        "Journey", 
        new { area = productType }, 
        this.Request.Url!= null? this.Request.Url.Scheme : "http"
    );
    

    然而,通常需要获取当前页面的URL,对于使用 Html.Action 的那些情况,并且将他的名字和控制器放在我身上感觉很尴尬 . 在这种情况下,我的偏好是使用JavaScript代替 . 这在半重写的系统中特别好.MVT半网络形式半个vb脚本半知道什么 - 并且要获取当前页面的URL每次需要使用不同的方法 .

    一种方法是使用JavaScript获取URL是 window.location.href 另一个 - document.URL

相关问题