【问题标题】:Getting Absolute URL from an ASP.NET MVC Action从 ASP.NET MVC 操作中获取绝对 URL
【发布时间】: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 上。

标签: c# asp.net-mvc asp.net-mvc-3


【解决方案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 的应用设置中。
        • 硬编码值。

        【讨论】:

          猜你喜欢
          • 2011-07-18
          • 2010-09-30
          • 1970-01-01
          • 2011-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-09
          相关资源
          最近更新 更多