如何在ASP.NET MVC中获取Web应用程序的基本URL?


300

如何快速确定ASP.NET MVC应用程序的根URL?也就是说,如果IIS设置为通过http://example.com/foo/bar为我的应用程序提供服务,那么我希望能够以一种可靠的方式获取该URL,而无需涉及从请求并以某种易碎的方式将其切碎,如果我重新路由操作,该方法会中断。

我需要基本URL的原因是,此Web应用程序调用了另一个需要回调方Web应用程序根的应用程序。

Answers:


399

假设您有一个Request对象可用,则可以使用:

string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

如果不可用,可以通过上下文进行访问:

var request = HttpContext.Current.Request

8
什么urlHelper.Content("~")啊 如何创建定义urlHelper?谢谢!
Maxim Zaslavsky 2010年

31
@Maxim,您可以替换Url.Content(“〜”)
UpTheCreek 2010年

13
我最终使用的是:var request = HttpContext.Current.Request; urlBase = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, (new System.Web.Mvc.UrlHelper(request.RequestContext)).Content("~"));
Peter

7
对于MVC 4我使用ControllerContext.RequestContext.HttpContext.Request
ROW1

6
@Url.Content("~")解析为"/",这不是基本网址。
安德鲁·霍夫曼

114

因此,这里列出的所有方法都不适合我,但是使用一些答案,我得到了一些有用的方法:

public string GetBaseUrl()
{
    var request = HttpContext.Current.Request;
    var appUrl = HttpRuntime.AppDomainAppVirtualPath;

    if (appUrl != "/") 
        appUrl = "/" + appUrl;

    var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);

    return baseUrl;
}

ASP.NET Core / MVC 6的更新:

ASP.NET Core使此过程更加痛苦,尤其是如果您深入了解代码。您有2个选择可前往HttpContext

1)从您的controller

var model = new MyClass(HttpContext);

然后在model

private HttpContext currentContext;

public MyClass(HttpContext currentContext)
{
    this.currentContext = currentContext;
}

2)也许更干净的方法是将其注入您的类中,首先在您的类中注册类型 Startup:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<MyClass, MyClass>();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

然后像这样为您注入它:

private HttpContext currentContext;

public MyClass(IHttpContextAccessor httpContextAccessor)
{
    currentContext = httpContextAccessor.HttpContext;
}

无论哪种情况,这都是针对的更新.NET Core GetBaseUrl()

public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

    return $"{request.Scheme}://{host}{pathBase}";
}

您在哪里放置了此方法?
乔什·迪安

3
这实际上取决于您需要使用它的频率...如果这是一次性使用协议,则将其放在需要此数据的类中,如果您预计在应用程序的多个类中使用它,则我使用文件夹Helpers在我的应用程序的底部调用,我有一个static名为的类,Statics并且在其中放置了类似上面的功能...只需确保将上面的内容更改public string GetBaseUrl()public static string GetBaseUrl()
Serj Sagan

作为更新,我不再使用名为的类Statics,而是将其分解成更特定的用途,因此在这种情况下,它将进入我的UrlHelper类中
Serj Sagan

1
在我发现的所有选项中,这是唯一对我有效的选项。您的#2是。谢谢一群!
adeldegan

2
提出这一建议是因为它是唯一提及PathBase的人,而这正是我所需要的。谢谢!
戴夫

69

在代码中:

Url.Content("~/");

MVC3 Razor语法:

@Url.Content("~/")

11
这对于在Razor页面上使用是很好的选择,但是如果您尝试将URL传递给外部资源,则不会提供完整的URL。
krillgar

5
没用 它只会添加/而不是实际名称。
Mrchief '16

2
Url帮手可以立即在哪里找到Code ?也许只有在Controller。当然不是在ViewModel或其他任何class地方,你可能需要这个..
Serj萨根

43

也许是对此处发布答案的扩展或修改,但我仅使用以下几行,即可正常工作:

Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")

当我的路径是:http://host/iis_foldername/controller/action
然后我收到:http://host/iis_foldername/


26

以下代码段在MVC4中非常适合我,不需要HttpContext可用的代码段:

System.Web.HttpRuntime.AppDomainAppVirtualPath

似乎也可以在MVC3中工作。我使用它jQuery.load()来构造要调用的控制器和操作的URL: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe 2012年

为什么要这么做?而不是调用Url.Action?
BlackTigerX 2014年

4
部署到Azure时不起作用。在这种情况下,评分较高的答案会起作用。
杰夫·邓洛普

25

依赖IIS的窍门是IIS绑定可以不同于您的公共URL(我正在看的WCF),尤其是在多宿主生产机器上。我倾向于引导使用配置为外部目的显式定义“基本” URL,因为这比从Request对象中提取URL更为成功。


2
对于负载均衡器或代理后面的服务器也是如此。
Ishmaeel 2014年

20

对于绝对基本URL,请使用此选项。可与HTTP和HTTPS一起使用。

new Uri(Request.Url, Url.Content("~"))

15

这是asp.net属性到MVC的转换。几乎所有的人都跳舞,所有跳舞都获得root url方法。

声明一个助手类:

namespace MyTestProject.Helpers
{
    using System.Web;

    public static class PathHelper
    {
        public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
        {
            string appPath = string.Empty;

            if (httpRequestBase != null)
            {
                //Formatting the fully qualified website url/name
                appPath = string.Format("{0}://{1}{2}{3}",
                            httpRequestBase.Url.Scheme,
                            httpRequestBase.Url.Host,
                            httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
                            httpRequestBase.ApplicationPath);
            }

            if (!appPath.EndsWith("/"))
            {
                appPath += "/";
            }

            return appPath;
        }
    }
}

用法:

要从控制器使用:

PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)

要在视图中使用:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
这是唯一说明可能在80以外的端口上运行站点的可能性的答案。就我而言,所有其他答案都不安全。谢谢!
jebar8

12

在MVC _Layout.cshtml中:

<base href="@Request.GetBaseUrl()" />

那就是我们用的!

public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
        {
          if (request.Url == (Uri) null)
            return string.Empty;
          else
            return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
        }
}

+1以使用<base>。您也可以省略该计划,使其可以与http或https一起使用。这意味着您可以使用开头URL //
杰西

5

这对我来说很好(也适用于负载均衡器):

@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content(“~”);
}

<script>
    var base_url = "@baseurl";
</script>

尤其是如果您使用的是非标准端口号,则使用Request.Url.Authority乍一看似乎很不错,但是在LB环境中失败。


3

您可以有一个静态方法来查看HttpContext.Current并根据主机ID决定使用哪个URL(开发或实时服务器)。HttpContext甚至可以提供一些更简单的方法来完成此操作,但这是我发现的第一个选项,并且效果很好。


3

您可以在视图中使用以下脚本:

<script type="text/javascript">
    var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>


3

这在ASP .NET MVC中有效4在任何控制器操作中,您都可以编写:1stline获取整个url + Query String。第二行删除本地路径和查询,最后一个'/'符号。第三行在最后一个位置添加“ /”符号。

Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );



3

在网页本身上:

<input type="hidden" id="basePath" value="@string.Format("{0}://{1}{2}",
  HttpContext.Current.Request.Url.Scheme,
  HttpContext.Current.Request.Url.Authority,
  Url.Content("~"))" />

在javascript中:

function getReportFormGeneratorPath() {
  var formPath = $('#reportForm').attr('action');
  var newPath = $("#basePath").val() + formPath;
  return newPath;
}

这适用于我的MVC项目,希望对您有所帮助


@hemp编辑过,但未投票赞成?希望这些点对您有价值
Andrew Day

这个问题和相关的答案对我的特定问题没有帮助,所以我没有尝试或投票给他们。我编辑了这个,是因为我偶然看到它,并认为如果格式正确,它可能是一个不错的答案。只是想成为一个好公民。
大麻

同样,编辑答案也没有获得声誉点。


2

也许这是一个更好的解决方案。

@{
   var baseUrl = @Request.Host("/");
}

使用

<a href="@baseUrl" class="link">Base URL</a>

1
我没有进行测试,但是我怀疑当基本URL直接是虚拟的时,这是否可以工作。即。localhost / myApp
整理


1

以下内容对我很有帮助

var request = HttpContext.Request;
                        var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;

                        if (appUrl != "/")
                            appUrl = "/" + appUrl + "/";

                        var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");


1

这是我的解决方案(在api控制器中使用.net core 3.1):

string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";



0

在项目的静态类(如实用程序类)中添加此函数:

utility.cs内容:

public static class Utility
{
    public static string GetBaseUrl()
    {
        var request = HttpContext.Current.Request;
        var urlHelper = new UrlHelper(request.RequestContext);
        var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
        return baseUrl;
    }
}

可以在任何地方使用此代码并享受它:

var baseUrl = Utility.GetBaseUrl();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.