ASP.NET中获取当前域的最佳方法是什么?


102

我想知道获取当前域的最佳方法是在ASP.NET中吗?

例如:

http://www.domainname.com/subdir/应该产生http://www.domainname.com http://www.sub.domainname.com/subdir/应该产生http://sub.domainname.com

作为指导,我应该可以直接在URL上添加一个URL,例如“ /Folder/Content/filename.html”(例如,由ASP.NET MVC中的Url.RouteUrl()生成)。


3
请注意,这里的“当前域”实际上是使用方用户代理用来访问您的网站的内容,在许多情况下,它与您网站的“官方URL”以及最终用户可能在浏览器中输入的内容不同(反向代理,转发代理,内部主机名,IP地址...)。
bzlm

1
因此,有没有一种方法可以获取“官方URL”(来自IIS的URL)?
Matt Mitchell

Answers:


186

答案与MattMitchell相同,但有所修改。而是检查默认端口。

编辑:更新了语法并Request.Url.Authority按照建议使用

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"

3
是否在.NET中定义了一个字段,我可以使用它代替“:”?像System.Uri.PortDelimiter一样?您知道,只是为了保持一致性。:)
Jan Aagaard

2
我不知道,扬·阿加德(Jan Aagaard),但您总是可以在本地制作一个。对于大多数“魔术”字符串和数字,我都会这样做。为此,您将在
string中

8
您可以Request.Url.Authority按照Korayem的建议使用,而不要使用Request.Url.Hostand Request.Url.Port
Schmalls 2012年

4
而不是连接字符串,您应该使用System.UriBuilder类。
BrainSlugs83

3
@MattMitchell,似乎无法与管理局创办了问题,这是主机的+相当于“:” +端口,看看源代码dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/...
朱塞佩Romagnuolo

40

根据此链接,一个好的起点是:

Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host 

但是,如果域为http://www.domainname.com:500,则此操作将失败。

诸如此类的东西很想解决此问题:

int defaultPort = Request.IsSecureConnection ? 443 : 80;
Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host 
  + (Request.Url.Port != defaultPort ? ":" + Request.Url.Port : "");

但是,端口80和443将取决于配置。

因此,您应按上述CarlosMuñoz IsDefaultPort的“已接受答案”中的方法使用。


1
为什么在这里使用80端口?如果删除该假设,则代码看起来像是万能的。当您使用端口80时,在许多情况下都将失败(请参阅有关其他响应的评论)。如果要删除端口号(如果可能),则必须检查该端口号是否为所用方案的默认端口,并且该方案支持默认端口号。
bzlm

是的,看到端口80可能不是一个好主意。我对此一无所知,这就是为什么我提到它需要依赖于配置。
马特·米切尔

1
我不知道这是否会有所帮助,但您也可以尝试:是否使用Request.IsSecureConnection确定是否使用HTTPS?
埃里克·布朗

1
@EricBrown-是的,五年后的回想起来,这个答案不是很好。我会选择CarlosMuñoz接受的答案来避免该问题。
马特·米切尔

29
Request.Url.GetLeftPart(UriPartial.Authority)

这是包含的方案。


23
我很想参加会议,当时他们
想到

20

警告!对于使用Current.Request .Url.Host的任何人。了解您是基于当前请求进行工作的,并且当前请求永远不会与您的服务器一起使用,有时可能与其他服务器一起使用。

因此,如果在Global.asax中的Application_BeginRequest()中使用它,则99.9%的时间是可以的,但0.1%的时间可能会得到您自己服务器的主机名以外的东西。

我不久前发现的东西就是一个很好的例子。我的服务器有时会不定期访问http://proxyjudge1.proxyfire.net/fastenv。Application_BeginRequest()很乐意处理此请求,因此,如果在发出此请求时调用Request.Url.Host,则会取回proxyjudge1.proxyfire.net。你们中有些人可能会想“不做”,但值得注意的是,由于它仅在0.1%的时间内发生,所以这是一个很难发现的错误:P

此错误迫使我将域主机作为字符串插入配置文件中。


完全一样。我的域现在在web.config中。
Korayem 2011年

我明白了-为什么您的服务器命中proxyfire?那是你的网站吗?但是,总的来说,这很有意义-在特定于应用程序的事件中使用特定于请求的对象可能效果不佳。在特定于请求的事件中是否存在危险,例如页面生命周期事件(Page.LoadCompleted等)?
mlhDev 2012年

对于它为什么要解决代理火灾问题,我并没有进行过多的调查。当然,这不是我的网站,但确实向我表明Current.Request.Url不是100%可靠。经过大量研究,我还发现动态确定您的主机名并不容易,这是因为多个NIC卡,IP和域名可以解析为同一IP。至于您的其他问题,马特,我不确定您的意思:(
Thirlan 2012年

所以这只发生在Application_BeginRequest吗?除非您未设置主机头,否则我看不出IIS如何将此请求发送到您的应用程序?
Simon_Weaver

@Thirlan-我正在尝试调试听起来与此类似的问题。我正在尝试使用Request.Url.Host获得子域,并且“通常”运行良好,但并非总是如此。真的有这件事吗?像请求中的其他内容一样可能正确吗?
scojomodena 2014年

14

为什么不使用

Request.Url.Authority

它返回整个域和端口。

您仍然需要输入http或https


2
这也可以。要“显示” http或https,请在simlpy之前加上“ //”。因此,例如,它将显示为href =“ // @@ Request.Url.Authority ...”
EdwardM

2

简单短期的方式(它支持架构,域和端口):

Request.GetFullDomain()

// Add this class to your project
public static class HttpRequestExtensions{
    public static string GetFullDomain(this HttpRequestBase request)
    {
        var uri= request?.UrlReferrer;
        if (uri== null)
            return string.Empty;
        return uri.Scheme + Uri.SchemeDelimiter + uri.Authority;
    }
}

// Now Use it like this:
Request.GetFullDomain();
// Example output:    https://www.example.com:5031
// Example output:    http://www.example.com:5031
// Example output:    https://www.example.com

1

其他方式:


string domain;
Uri url = HttpContext.Current.Request.Url;
domain= url.AbsoluteUri.Replace(url.PathAndQuery, string.Empty);

简单但简单的答案!
Shiroy

1

怎么样:

NameValueCollection vars = HttpContext.Current.Request.ServerVariables;
string protocol = vars["SERVER_PORT_SECURE"] == "1" ? "https://" : "http://";
string domain = vars["SERVER_NAME"];
string port = vars["SERVER_PORT"];

0

使用UriBuilder:

    var relativePath = ""; // or whatever-path-you-want
    var uriBuilder = new UriBuilder
    {
        Host = Request.Url.Host,
        Path = relativePath,
        Scheme = Request.Url.Scheme
    };

    if (!Request.Url.IsDefaultPort)
        uriBuilder.Port = Request.Url.Port;

    var fullPathToUse = uriBuilder.ToString();

-1

怎么样:

String domain = "http://" + Request.Url.Host

不错,但是如果您的站点具有安全页面,即https://,如果您的域未托管在端口80上怎么办?
马特·米切尔
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.