如何快速确定ASP.NET MVC应用程序的根URL?即,如果IIS设置为在http://example.com/foo/bar上提供我的应用程序,那么我希望能够以可靠的方式获取该URL,而不涉及从当前URL获取当前URL请求并以一些脆弱的方式将其砍掉,如果我重新路由我的行动就会中断.
我需要基本URL的原因是此Web应用程序调用另一个需要root用户来调用Web应用程序以进行回调.
假设您有一个Request对象,您可以使用:
string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
如果它不可用,您可以通过上下文访问它:
var request = HttpContext.Current.Request
所以这里列出的没有一个适合我,但是使用了一些答案,我得到了一些工作:
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
:
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(); services.TryAddSingleton (); }
然后让它为你注入这样:
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}"; }
在代码中:
Url.Content("~/");
MVC3 Razor语法:
@Url.Content("~/")
也许它是对此处发布的答案的扩展或修改,但我只使用以下行并且它有效:
Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")
我的路径是:http://host/iis_foldername/controller/action
然后我收到:http://host/iis_foldername/
依赖IIS的诀窍是IIS绑定可能与您的公共URL(我正在看着你的WCF)不同,特别是对于多宿主生产机器.我倾向于使用配置来明确定义用于外部目的的"基础"URL,因为这往往比从Request对象中提取它更成功.
以下代码片段适用于MVC4,并且不需要HttpContext
可用:
System.Web.HttpRuntime.AppDomainAppVirtualPath
对于绝对基本URL,请使用此选项.适用于HTTP和HTTPS.
new Uri(Request.Url, Url.Content("~"))
这是asp.net属性到MVC的转换.几乎所有人都在唱着所有跳舞的根网址方法.
声明一个辅助类:
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)
在MVC _Layout.cshtml中:
多数民众赞成我们用的!
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("~/"); } }
这对我来说很好(也有负载均衡器):
@{ var urlHelper = new UrlHelper(Html.ViewContext.RequestContext); var baseurl = urlHelper.Content(“~”); }
特别是如果您使用非标准端口号,使用Request.Url.Authority最初看起来像一个好的领导,但在LB环境中失败.