一次调用中包含Request.Url.Host和ApplicationPath的方法是什么?

18

有没有一种方法可以在一次调用中获取HttpContext.Current.Request.Url.HostHttpContext.Current.Request.ApplicationPath

就像"完整的应用程序URL"一样?

编辑:澄清 - 我需要的是[]内的部分:

http://[www.mysite.com/mywebapp]/Pages/Default.aspx

我只是出于好奇而提问。

编辑2:感谢所有回复,但它们都不完全是我正在寻找的。顺便说一句,我是这样解决问题的(但仍然想知道是否有更顺畅的方法):

public string GetWebAppRoot()
{
    if(HttpContext.Current.Request.ApplicationPath == "/")
        return "http://" + HttpContext.Current.Request.Url.Host;
    else
        return "http://" + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.ApplicationPath;
}

理论上你想要的是 Request.Url.Authority,但是 Host 没有端口。不幸的是,你最好使用 Request.Headers["HOST"] 中的内容,因为这个内容应该包含客户端用来连接服务器的 dns:port 信息。当然,如果你担心 HTTP/1.0 请求,你可以回退到 Request.Url.Host。我个人经验是 Request.Url.Authority 返回的是服务器软件绑定的端口,而不是 "HOST" 头部中的端口——这是客户端用来连接的端口。(顺带说一下,这是在 SSRS 2012 的 Report Manager 网站中发生的事情。) - Granger
6个回答

32
public static string GetSiteRoot()
{
  string port = System.Web.HttpContext.Current.Request.ServerVariables["SERVER_PORT"];
  if (port == null || port == "80" || port == "443")
    port = "";
  else
    port = ":" + port;

  string protocol = System.Web.HttpContext.Current.Request.ServerVariables["SERVER_PORT_SECURE"];
  if (protocol == null || protocol == "0")
    protocol = "http://";
  else
    protocol = "https://";

  string sOut = protocol + System.Web.HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + port + System.Web.HttpContext.Current.Request.ApplicationPath;

  if (sOut.EndsWith("/"))
  {
    sOut = sOut.Substring(0, sOut.Length - 1);
  }

  return sOut;
}

如果我没记错的话,SERVER_NAME可能无法获取您需要的主机名 - 例如主机标头解析(http://msdn.microsoft.com/en-us/library/ms524602.aspx)!如果我错了,请纠正我 :) - veggerby
2
我已经在不同的网站上使用了这个工具多年了 - 它会提供请求的服务器名称,从http://到第一个/。 - MartinHN
如果这个能用,非常感谢。一直在寻找一个能够处理非标准端口和像https://www.blah.com/web/test/hello.aspx这样的URL的东西。我会试一下的。 - infocyde
1
我从我的帖子中删除了“答案”标签,并将其移动到这里,因为此答案涵盖了更多情况。 - Marcus L

18

在我的本地主机上,使用端口号时这段代码无法运行,所以我进行了轻微的修改:

  private string GetWebAppRoot()
    {
        string host = (HttpContext.Current.Request.Url.IsDefaultPort) ? 
            HttpContext.Current.Request.Url.Host : 
            HttpContext.Current.Request.Url.Authority;
        host = String.Format("{0}://{1}", HttpContext.Current.Request.Url.Scheme, host);            
        if (HttpContext.Current.Request.ApplicationPath == "/")
            return host;
        else
            return host + HttpContext.Current.Request.ApplicationPath;
    }

7
你真正应该做的是:
return String.Format("{0}://{1}/", Request.Url.Scheme, Request.Url.Host);

那么,如果您正在使用HTTPS(或其他某些模式!),它就可以工作。

3

感谢所有的回复,但是它们都不完全符合我的需求。 顺便说一下,我是这样解决问题的(但还是想知道是否有更加顺畅的方法):

public string GetWebAppRoot()
{
    if(HttpContext.Current.Request.ApplicationPath == "/")
        return "http://" + HttpContext.Current.Request.Url.Host;
    else
        return "http://" + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.ApplicationPath;
}

是的,我的解决方案实际上并没有处理那个问题,但这个可以:return String.Format("{0}://{1}/", Request.Url.Scheme, Request.Url.Host); - Marcus L

2

Check this post:

public static Uri GetBaseUrl(HttpRequest request)
{
    Uri contextUri = new Uri(request.Url, request.RawUrl);
    UriBuilder realmUri = new UriBuilder(contextUri) { Path = request.ApplicationPath, Query = null, Fragment = null };
    return realmUri.Uri;
}

public static string GetAbsoluteUrl(HttpRequest request, string relativeUrl)
{
    return new Uri(GetBaseUrl(request), VirtualPathUtility.ToAbsolute(relativeUrl)).AbsoluteUri;
}

如果您不能直接从GetBaseUrl获得所需内容,可以尝试使用以下方法:GetAbsoluteUrl(HttpContext.Current.Request, "/")。这个方法可以帮助您获取绝对路径。请注意保留原有的HTML标签格式。

1
HttpContext.Current.Request.Url.AbsoluteUri

谢谢,但不要 - 这会给你返回调用它的 ASPX 页面的完整路径。我只想要主机和应用程序路径,而不是页面路径。 - Marcus L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接