关于.NET:如何在ASP.NET MVC中获取webapp的基URL?

How can I get my webapp's base URL in ASP.NET MVC?

如何快速确定我的ASP.NET MVC应用程序的根URL是什么?例如,如果将IIS设置为在http://example.com/foo/bar上为我的应用程序提供服务,那么我希望能够以可靠的方式获取该URL,而不涉及从请求中获取当前的URL,并以脆弱的方式将其切碎,如果我重新路由我的操作,则会中断。

我需要基本URL的原因是,此Web应用程序调用另一个需要调用者Web应用程序根目录以进行回调的应用程序。


假设您有可用的请求对象,您可以使用:

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

如果它不可用,您可以通过上下文访问它:

1
var request = HttpContext.Current.Request


所以这里列出的所有答案对我来说都不管用,但通过几个答案,我得到了一些有用的东西:

1
2
3
4
5
6
7
8
9
10
11
12
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使这个过程更加痛苦,特别是在代码很深的时候。你有两个选择去HttpContext

1)从你的controller传过来:

1
var model = new MyClass(HttpContext);

然后在model中:

1
2
3
4
5
6
private HttpContext currentContext;

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

2)也许更干净的方法是将其注入类中,该类从在您的Startup:中注册类型开始。

1
2
3
4
5
6
7
8
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

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

然后像这样给你注射:

1
2
3
4
5
6
private HttpContext currentContext;

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

在任何一种情况下,这里都是针对.NET CoreGetBaseUrl()的更新:

1
2
3
4
5
6
7
8
9
10
public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

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


在代码中:

1
Url.Content("~/");

MVC3 Razor语法:

1
@Url.Content("~/")


也许这是对这里发布的答案的扩展或修改,但我只使用下面的一行就可以了:

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

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


依赖于IIS的诀窍是,IIS绑定可以不同于您的公共URL(我在看您的WCF),特别是在多家生产机器上。我倾向于使用配置为外部目的显式地定义"基"URL,因为这比从请求对象中提取URL更成功。


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

1
System.Web.HttpRuntime.AppDomainAppVirtualPath


对于绝对基URL,请使用此选项。同时使用HTTP和HTTPS。

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

这是ASP.NET属性到MVC的转换。这几乎是一个全唱全舞的获取根URL方法。

声明助手类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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;
        }
    }
}

用途:

从控制器使用:

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

在视图中使用:

1
2
3
@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)


在mvcu layout.cshtml中:

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

我们就是这么用的!

1
2
3
4
5
6
7
8
9
10
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
2
3
4
5
6
7
@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content("~");
}


    var base_url ="@baseurl";

特别是如果您使用的是非标准端口号,那么使用request.url.authority一开始看起来像是一个很好的线索,但在LB环境中失败了。


您可以有一个静态方法来查看httpcontext.current,并根据主机ID决定要使用哪个URL(开发或活动服务器)。httpcontext甚至可以提供一些更简单的方法来执行此操作,但这是我找到的第一个选项,它工作正常。


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

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

这在ASP.NET MVC 4中工作在任何控制器操作中,您都可以写入:1STLINE获取整个URL+查询字符串。第二行删除本地路径和查询,最后一个"/"符号。第3行在最后一个位置添加"/"符号。

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

在简单的HTML和ASP.NET或ASP.NET MVC中,如果使用的是标记:

1
About us


在网页上:

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

在javascript中:

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

这对我的MVC项目有效,希望能有所帮助。


对于ASP.NET MVC 4,它有点不同:

1
string url = HttpContext.Request.Url.AbsoluteUri;

我把这个放在我的Layout.cshtml的头上

1
 <base href="~/" />

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

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

使用

1
Base URL


对于具有应用别名的URL,如http://example.com/appalias/…您可以尝试以下操作:

1
2
var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);


对于MVC 4:

1
String.Format("{0}://{1}{2}", Url.Request.RequestUri.Scheme, Url.Request.RequestUri.Authority, ControllerContext.Configuration.VirtualPathRoot);