104

I am wondering what the best way to obtain the current domain is in ASP.NET?

For instance:

http://www.domainname.com/subdir/ should yield http://www.domainname.com http://www.sub.domainname.com/subdir/ should yield http://sub.domainname.com

As a guide, I should be able to add a url like "/Folder/Content/filename.html" (say as generated by Url.RouteUrl() in ASP.NET MVC) straight onto the URL and it should work.

Gulzar Nazim
  • 51,744
  • 26
  • 128
  • 170
Matt Mitchell
  • 40,943
  • 35
  • 118
  • 185
  • 3
    Note that the "current domain" here is actually what the consuming user-agent used to get to your site, which in many cases is different from your site's "official URL" as well as what the end user may have entered into their browser (reverse proxy, forward proxy, internal hostname, IP address, ...). – bzlm Apr 29 '09 at 16:06
  • 1
    So is there a way to get the "official URL" (the one from IIS?) – Matt Mitchell May 01 '09 at 03:02

11 Answers11

190

Same answer as MattMitchell's but with some modification. This checks for the default port instead.

Edit: Updated syntax and using Request.Url.Authority as suggested

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
Carlos Muñoz
  • 17,397
  • 7
  • 55
  • 80
  • 3
    Is there a field defined i .NET, that I can use instead of ":"? Something like System.Uri.PortDelimiter? You know, just for consistency. :) – Jan Aagaard Oct 17 '11 at 18:46
  • 2
    Not that I know of, Jan Aagaard, but you could always make one locally. I do that for most "magic" strings and numbers. For that matter, you would then use string.Empty instead of "" in Carlos' answer ;) – vbullinger Aug 10 '12 at 21:34
  • 8
    You can use `Request.Url.Authority` as Korayem suggested instead of the `Request.Url.Host` and `Request.Url.Port`. – Schmalls Aug 16 '12 at 16:25
  • @Schmalls - Authority seems to have issues, e.g. http://stackoverflow.com/questions/16060027/request-url-authority-doesnt-return-expected-domain – Matt Mitchell Jun 14 '13 at 09:57
  • 4
    Instead of concatenating strings, you should be using the System.UriBuilder class. – BrainSlugs83 Jun 16 '13 at 05:43
  • 3
    @MattMitchell, it seems not founded the issues with Authority, it is the equivalent of Host + ":" + Port, see source code http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/whidbey/REDBITS/ndp/fx/src/Net/System/URI@cs/9/URI@cs – Giuseppe Romagnuolo Feb 27 '14 at 16:17
  • @BrainSlugs83 I added an answer using UriBuilder. – Darren Apr 01 '15 at 07:29
42

As per this link a good starting point is:

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

However, if the domain is http://www.domainname.com:500 this will fail.

Something like the following is tempting to resolve this:

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

However, port 80 and 443 will depend on configuration.

As such, you should use IsDefaultPort as in the Accepted Answer above from Carlos Muñoz.

Community
  • 1
  • 1
Matt Mitchell
  • 40,943
  • 35
  • 118
  • 185
  • 1
    Why assume port 80 here? If you remove that assumption, the code looks like a catch-all. When you assume port 80, you will fail in many scenarios (see comments on other anwers). If you want to remove the port number if possible, you must check that the port number is the default for the scheme in question, and that the scheme supports default port numbers. – bzlm Apr 29 '09 at 16:03
  • Yeah see the note that port 80 may be a bad idea. I don't know any other way around this though which is why I mentioned it will need to be configuration dependant. – Matt Mitchell May 01 '09 at 03:08
  • 1
    I don't know if this will help or not but you could also try: if Request.IsSecureConnection to determine if HTTPS is used or not? – Erick Brown Jun 12 '13 at 19:44
  • 1
    @EricBrown - Yeah, this answer is not great in retropsect 5 years later. I'd go with Carlos Muñoz's accepted answer to avoid that issue. – Matt Mitchell Jun 14 '13 at 09:58
29
Request.Url.GetLeftPart(UriPartial.Authority)

This is included scheme.

izlence
  • 291
  • 3
  • 2
20

WARNING! To anyone who uses Current.Request.Url.Host. Understand that you are working based on the CURRENT REQUEST and that the current request will not ALWAYS be with your server and can sometimes be with other servers.

So if you use this in something like, Application_BeginRequest() in Global.asax, then 99.9% of the time it will be fine, but 0.1% you might get something other than your own server's host name.

A good example of this is something I discovered not long ago. My server tends to hit http://proxyjudge1.proxyfire.net/fastenv from time to time. Application_BeginRequest() gladly handles this request so if you call Request.Url.Host when it's making this request you'll get back proxyjudge1.proxyfire.net. Some of you might be thinking "no duh" but worth noting because it was a very hard bug to notice since it only happened 0.1% of the time : P

This bug has forced me to insert my domain host as a string in the config files.

Thirlan
  • 712
  • 1
  • 8
  • 26
  • Did exactly the same. My domain is in web.config now. – Korayem Dec 14 '11 at 21:57
  • i _think_ i understand, though - why does your server hit proxyfire? Is that your site? But, overall, makes sense - using a request-specific object during an application-specific event may not work too well. Is there a danger in a request-specific event, like a page life cycle event (Page.LoadCompleted, etc.)? – mlhDev Oct 16 '12 at 13:00
  • I didn't investigate too hard as to why it was resolving to proxyfire. It certainly wasn't my site, but it did indicate to me that Current.Request.Url was not 100% reliable. After a lot of research I had also discovered that dynamically determining your hostname is not easy, due to multiple NIC cards, IPs and domain names that resolve to the same IP. As for your other question Matt, I'm not sure what you mean : ( – Thirlan Oct 17 '12 at 14:09
  • so this only ever occured in Application_BeginRequest? I don't see how IIS could have ever sent this request to your app unless you have no host header set perhaps? – Simon_Weaver Feb 08 '13 at 05:42
  • @Thirlan - I am trying to debug an issue that sounds similar to this. I am trying to get the subdomain using Request.Url.Host and 'usually' works well, but not always. Is there really anyway around this? Like something else in the request that may be correct? – scojomodena Nov 12 '14 at 15:01
  • I did a lot of reading on this at the time and unfortunately the only foolproof way is to hardcode. – Thirlan Nov 18 '14 at 06:08
14

Why not use

Request.Url.Authority

It returns the whole domain AND the port.

You still need to figure http or https

Korayem
  • 12,108
  • 5
  • 69
  • 56
  • 2
    This works too. To "figure" http or https, simlpy put "//" before it. So for example it would read as href="//@Request.Url.Authority..." – EdwardM Nov 02 '16 at 23:23
3

Simple and short way (it support schema, domain and port):

Use 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://example.com:5031
// Example output:    http://example.com:5031
Dastan Alybaev
  • 309
  • 4
  • 12
Ramin Bateni
  • 16,499
  • 9
  • 69
  • 98
1

Another way:


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

In Asp.Net Core 3.1 if you want to get a full domain, here is what you need to do:

Step 1: Define variable

private readonly IHttpContextAccessor _contextAccessor;

Step 2: DI into the constructor

public SomeClass(IHttpContextAccessor contextAccessor)
{
    _contextAccessor = contextAccessor;
}

Step 3: Add this method in your class:

private string GenerateFullDomain()
{
    string domain = _contextAccessor.HttpContext.Request.Host.Value;
    string scheme = _contextAccessor.HttpContext.Request.Scheme;
    string delimiter = System.Uri.SchemeDelimiter;
    string fullDomainToUse = scheme + delimiter + domain;
    return fullDomainToUse;
}
//Examples of usage GenerateFullDomain() method:
//https://example.com:5031
//http://example.com:5031
Dastan Alybaev
  • 309
  • 4
  • 12
1

How about:

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"];
Mike Corcoran
  • 14,072
  • 4
  • 37
  • 49
derek lawless
  • 2,544
  • 2
  • 16
  • 13
0

Using 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();
Darren
  • 9,014
  • 2
  • 39
  • 50
-1

How about:

String domain = "http://" + Request.Url.Host
jwalkerjr
  • 1,779
  • 4
  • 18
  • 20