从 ASP.NET MVC 操作中获取绝对 URL

Posted

技术标签:

【中文标题】从 ASP.NET MVC 操作中获取绝对 URL【英文标题】:Getting Absolute URL from an ASP.NET MVC Action 【发布时间】:2011-09-13 17:54:39 【问题描述】:

这可能是一个虚拟问题,但我找不到明确的指示。我在 MVC3 Web 应用程序中有一个 POCO 类,其唯一目的是管理服务器中某些文件的备份。通常它会创建一个备份并将文件名返回给控制器,控制器会发送一封电子邮件,其中包含用于下载它的 URL。这工作正常,但我无法构建要发送的绝对 URL。无论我使用哪个函数,我总是得到一个相对 URL,例如 /Backup/TheFile.zip,而不是例如http://www.somesite.com/Backup/TheFile.zip。我试过了:

VirtualPathUtility.ToAbsolute("~/Backup/SomeFile.zip");
HttpRuntime.AppDomainAppVirtualPath + "/Backup/SomeFile.zip";
Url.Content("~/Backup/SomeFile.zip");

但它们都返回类似 /Backup/SomeFile.zip 的内容。有什么想法吗?

【问题讨论】:

答案here 在类似的情况下帮助了我。这个答案解决了 http/https 和端口号。这非常有用,因为我的本地开发是在带有端口号的 http 上,但生产解决方案是在 https 上。 【参考方案1】:

您可以通过以下方式做到这一点:

var urlBuilder =
    new System.UriBuilder(Request.Url.AbsoluteUri)
        
            Path = Url.Action("Action", "Controller"),
            Query = null,
        ;

Uri uri = urlBuilder.Uri;
string url = urlBuilder.ToString();
// or urlBuilder.Uri.ToString()

除了此示例中的Url.Action(),您还可以使用Url.Content(),或任何路由方法,或者实际上只是传递路径。

但如果 URL 确实转到 Controller Action,还有一种更紧凑的方式:

var contactUsUriString =
    Url.Action("Contact-Us", "About",
               routeValues: null /* specify if needed */,
               protocol: Request.Url.Scheme /* This is the trick */);

这里的诀窍是,一旦你在调用任何路由方法时指定了protocol/scheme,你就会得到一个绝对 URL。 我尽可能推荐这个,但如果需要,您也可以在第一个示例中使用更通用的方法。

我已经在博客中详细介绍了它:http://gurustop.net/blog/2012/03/23/writing-absolute-urls-to-other-actions-in-asp-net-mvc/

摘自Meligy’s AngularJS & Web Dev Goodies Newsletter

【讨论】:

已编辑:如果您的请求 Uri 有查询段,您可能还需要覆盖 Uri 构建器上的 Query 属性! 这是一个包含所有选项的快速摘要帖子:benjii.me/2015/05/…【参考方案2】:

从控制器内部:

var path = VirtualPathUtility.ToAbsolute(pathFromPoco);
var url = new Uri(Request.Url, path).AbsoluteUri

【讨论】:

VirtualPathUtility 仍然返回 MVC4 控制器中的相对 Uri 结合 Uri 类,这就是你所需要的。一种毫无意义的评论。 我将首先通过 Url.Content() 方法传递您的路径。对于非绝对路径(以“/”开头),此答案将失败。【参考方案3】:

这对我有用:

using System;
using System.Web;
using System.Web.Mvc;

public static class UrlExtensions

    public static string Content(this UrlHelper urlHelper, string contentPath, bool toAbsolute = false)
    
        var path = urlHelper.Content(contentPath);
        var url = new Uri(HttpContext.Current.Request.Url, path);

        return toAbsolute ? url.AbsoluteUri : path;
    

在cshtml中的使用:

@Url.Content("~/Scripts/flot/jquery.flot.menuBar.js", true)

【讨论】:

这很棒。实际上,我几乎完全按照您在回答中的建议编写了内容,但没有考虑将其添加为 Content 方法的覆盖以使其更加精简。谢谢! 非常感谢您提供的出色解决方案。我正在使用 ng-include 指令,但由于相对路径,我遇到了很多问题。我在您的代码中添加的唯一内容是 '' 围绕 url。【参考方案4】:

如果 hostprotocol 参数不为空,MVC 4 中的内置帮助程序会创建绝对 URL。请参阅 this answer here 以及在视图中使用的示例扩展方法。

【讨论】:

【参考方案5】:

在 ASP.Net Core 2.0 (MVC) 中,这可以创建一个动作的绝对 URL。

var url = Url.Action("About", "Home", new  /*Route values here*/ , Request.Scheme);

【讨论】:

【参考方案6】:

我为此编写了一个辅助类,用于 MVC 5... 它非常灵活,如果您不在控制器中时需要此功能,则特别有用。您应该能够将其直接放入项目中并继续。

正如 Meligy 所指出的,关键是包含协议。在这里,我将其硬编码为 http,因此如果您想使用 SSL,可能需要变得更灵活一些。

public class AbsoluteUrlHelper

    /// <summary>
    /// Creates an absolute "fully qualified" url from an action, and assumes the current controller.
    /// </summary>
    /// <returns></returns>
    public static string GetAbsoluteUrl(string action, object routeValues = null)
    
        var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
        var values = urlHelper.RequestContext.RouteData.Values;
        var controller = values["controller"].ToString();

        return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
    

    /// <summary>
    /// Creates an absolute "fully qualified" url from an action and controller.
    /// </summary>
    public static string GetAbsoluteUrl(string action, string controller, object routeValues = null)
    
        var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);

        return GetAbsoluteUrl(action, controller, urlHelper, routeValues);
    

    /// <summary>
    /// Creates an absolute "fully qualified" url from an action and controller.
    /// </summary>
    public static string GetAbsoluteUrl(string action, string controller, UrlHelper urlHelper, object routeValues = null)
    
        var uri = urlHelper.Action(action, controller, routeValues, "http");

        return uri;
    

【讨论】:

【参考方案7】:

你有几个选择:

将 HttpContext.Request.Url 的值保存在静态或成员变量中,并使用它来传递完全限定路径。 将应用域保存在 web.config 的应用设置中。 硬编码值。

【讨论】:

以上是关于从 ASP.NET MVC 操作中获取绝对 URL的主要内容,如果未能解决你的问题,请参考以下文章

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

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

csharp asp.net mvc路由的绝对URL

asp.net mvc怎样传递多个url参数

Asp.Net MVC:如何获取当前控制器/视图的虚拟 url?

ASP.NET MVC - 从控制器中查找 App_Data 文件夹的绝对路径