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

Posted

技术标签:

【中文标题】在 ASP.NET MVC 中获取操作的完整 URL [重复]【英文标题】:Getting full URL of action in ASP.NET MVC [duplicate] 【发布时间】:2011-01-01 14:23:00 【问题描述】:

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

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

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

【问题讨论】:

另见:***.com/q/434604 【参考方案1】:

有一个 Url.Action 的重载,它将您想要的协议(例如 http、https)作为参数 - 如果您指定它,您将获得一个完全限定的 URL。

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

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>

【讨论】:

没关系 - 你会认为应该还有更好的方法来做这件事,但是嘿...... 正确的 url 是 https://127.0.0.1/Home/Index,但它会生成 https://127.0.0.1:444/Home/Index。它必须没有端口。我在 Azure 模拟器上运行。请帮忙。 @fiberOptics - 对你来说已经很晚了,但对其他人来说:你遇到的问题是你在非标准端口上运行 Azure 模拟器(通常有一个关于它的注释它开始),因此这项工作需要端口。在生产中,它应该使用标准端口 (443),因此它不会包含在 URL 中。 在 MVC6 中我是这样做的 &lt;a href="@Url.Action("Login", "Account", null, Context.Request.Scheme)"&gt;Log in&lt;/a&gt; 这不起作用;它失去了港口。如果您的网站在非标准端口上运行,则会生成损坏的 URL【参考方案2】:

正如 Paddy 所提到的:如果您使用明确指定要使用的协议的 UrlHelper.Action() 重载,则生成的 URL 将是绝对的和完全限定的,而不是相对的。

我写了一篇名为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")

【讨论】:

希望你得到更多的支持,这实际上是一个理所当然的事情,应该在 IMO 框架中 我唯一要添加(或修改)的是用 HttpContext.Current.Request.Url.Scheme 替换文字“http”。这将允许在适当的时候使用 https。 使用原始 URL 中的方案确保您不会错误地从 HTTPS 移动到 HTTP。防止 TLS 泄露。你得到我的投票。 @AndreasLarsen 嗯,您确定这是您问题的解决方案吗?从技术上讲,上述扩展方法除了使用当前 HTTP 请求的方案调用 UrlHelper.Action 方法之外没有做任何其他事情。 这很棒。谢谢。小提示...为了 VS 自动完成,方法名称“ActionAbsolute”会是更好的选择,因为 Url.Action() 将位于 Url.ActionAbsolute() 旁边。【参考方案3】:

这是你需要做的。

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

【讨论】:

这与接受的答案相同。最好在引入新内容时发布答案。【参考方案4】:

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

更新:在页面本身之外形成 url 的方法在上面的答案中有很好的描述。

或者你可以像下面这样做一个单行:

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 一半 web-forms 一半 vb-script 一半天知道是什么的系统中特别好 - 并且要获取当前页面的 URL,每次都需要使用不同的方法。

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

【讨论】:

这只会显示当前页面的 URL。 OP 想要做的是传递 .Net 控制器和视图的名称以生成 URL 以访问该页面。【参考方案5】:

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

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

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

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

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

【讨论】:

Request.Url.Schema 使用“当前请求”的模式来确定 HTTP 与 HTTPS。如果您的锚标记是由 HTTP 请求生成的,那么架构将不是 HTTPS。硬编码一个安全协议似乎很好;我不认为这样做是“作弊”,我很惊讶其他答案没有承认将Request.Url.Schema 用于同时提供 HTTP 和 HTTPS 资源的站点可能是一个问题。如果协议需要在不同的环境中有所不同,App Settings / Web Config 可能是要走的路。【参考方案6】:

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

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

    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>

这肯定是更多的工作,但知道编译时验证就在我身边,我很放心。

【讨论】:

url类和控制器类存放在哪里? 随心所欲! 你也可以在 Action 方法上使用 nameof 操作符。

以上是关于在 ASP.NET MVC 中获取操作的完整 URL [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在ASP.NET MVC 中获取当前URLcontrolleraction

在ASP.NET MVC 中获取当前URLcontrolleraction(转)

如何在 ASP.NET MVC 操作中获取引荐来源网址?

使用文件操作方法时如何在 ASP.NET MVC 中获取文件的 ContentType

ASP.NET MVC 5 - 身份。如何获取当前的ApplicationUser

ASP.NET MVC - 如何获取 URL 而不是操作链接?