Какой лучший метод в ASP.NET для получения текущего домена?

Мне интересно, как лучше всего получить текущий домен в ASP.NET?

Например:

http://www.domainname.com/subdir/ должен дать http://www.domainname.com http://www.sub.domainname.com/subdir/ должно привести к http://sub.domainname.com

В качестве руководства я должен иметь возможность добавить URL-адрес типа «/Folder/Content/filename.html» (скажем, созданный Url.RouteUrl () в ASP.NET MVC) прямо в URL-адрес, и он должен работать.


person Matt Mitchell    schedule 15.09.2008    source источник
comment
Обратите внимание, что текущий домен здесь на самом деле является тем, что пользовательский агент-потребитель использовал для доступа к вашему сайту, который во многих случаях отличается от официального URL-адреса вашего сайта, а также от того, что конечный пользователь мог ввести в свой браузер (обратный прокси, пересылка прокси, внутреннее имя хоста, IP-адрес, ...).   -  person bzlm    schedule 29.04.2009
comment
Итак, есть ли способ получить официальный URL-адрес (тот, что от IIS?)   -  person Matt Mitchell    schedule 01.05.2009


Ответы (11)


Тот же ответ, что и у Мэтта Митчелла, но с некоторыми изменениями. Вместо этого проверяется порт по умолчанию.

Изменить: обновленный синтаксис и использование Request.Url.Authority, как было предложено

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
person Carlos Muñoz    schedule 20.05.2010
comment
В .NET определено ли поле, которое я могу использовать вместо:? Что-то вроде System.Uri.PortDelimiter? Знаете, просто для последовательности. :) - person Jan Aagaard; 17.10.2011
comment
Не то, чтобы я знал о Яне Огарде, но вы всегда можете сделать его на месте. Я делаю это для большинства волшебных строк и чисел. В этом случае вы бы использовали string.Empty вместо ответа Карлоса;) - person vbullinger; 11.08.2012
comment
Вы можете использовать Request.Url.Authority, как предложил Кораем, вместо Request.Url.Host и Request.Url.Port. - person Schmalls; 16.08.2012
comment
@Schmalls - Кажется, у властей есть проблемы, например stackoverflow.com/questions/16060027 / - person Matt Mitchell; 14.06.2013
comment
Вместо объединения строк следует использовать класс System.UriBuilder. - person BrainSlugs83; 16.06.2013
comment
@MattMitchell, похоже, проблем с Authority не обнаружено, это эквивалент Host +: + Port, см. Исходный код dotnetframework.org/default.aspx/DotNET/DotNET/8@ 0 / untmp / - person Giuseppe Romagnuolo; 27.02.2014
comment
@ BrainSlugs83 Я добавил ответ с помощью UriBuilder. - person Darren; 01.04.2015

Согласно этой ссылке хорошей отправной точкой является:

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 будет зависеть от конфигурации.

Поэтому вам следует использовать IsDefaultPort, как в принятом ответе Карлоса Муньоса выше.

person Matt Mitchell    schedule 15.09.2008
comment
Зачем считать здесь 80-й порт? Если вы уберете это предположение, код станет универсальным. Когда вы предполагаете, что порт 80, вы потерпите неудачу во многих сценариях (см. Комментарии к другим ответам). Если вы хотите удалить номер порта, если это возможно, вы должны убедиться, что номер порта является номером порта по умолчанию для рассматриваемой схемы и что схема поддерживает номера портов по умолчанию. - person bzlm; 29.04.2009
comment
Да, обратите внимание, что порт 80 может быть плохой идеей. Я не знаю другого способа обойти это, поэтому я упомянул, что это должно зависеть от конфигурации. - person Matt Mitchell; 01.05.2009
comment
Я не знаю, поможет ли это или нет, но вы также можете попробовать: if Request.IsSecureConnection, чтобы определить, используется ли HTTPS или нет? - person Erick Brown; 12.06.2013
comment
@EricBrown - Да, это не лучший ответ 5 лет спустя. Я бы пошел с принятым ответом Карлоса Муньоса, чтобы избежать этой проблемы. - person Matt Mitchell; 14.06.2013

Request.Url.GetLeftPart(UriPartial.Authority)

Это включенная схема.

person izlence    schedule 31.12.2011

ВНИМАНИЕ! Всем, кто использует Current.Request .Url.Host. Поймите, что вы работаете на основе ТЕКУЩЕГО ЗАПРОСА и что текущий запрос НЕ ВСЕГДА будет поступать с вашего сервера, а иногда может быть с другими серверами.

Так что, если вы используете это в чем-то вроде Application_BeginRequest () в Global.asax, то в 99,9% случаев все будет нормально, но в 0,1% вы можете получить что-то другое, кроме имени хоста вашего собственного сервера.

Хорошим примером этого является то, что я обнаружил недавно. Мой сервер имеет тенденцию время от времени попадать на http://proxyjudge1.proxyfire.net/fastenv. Application_BeginRequest () с радостью обработает этот запрос, поэтому, если вы вызовете Request.Url.Host, когда он делает этот запрос, вы получите обратно proxyjudge1.proxyfire.net. Некоторые из вас могут подумать «нет, черт возьми», но стоит отметить, потому что это было очень трудно заметить, так как это происходило только в 0,1% случаев: P

Эта ошибка вынудила меня вставить мой хост домена в виде строки в файлы конфигурации.

person Thirlan    schedule 30.04.2011
comment
Сделал точно так же. Мой домен сейчас находится в web.config. - person Korayem; 15.12.2011
comment
Я думаю, что понимаю - почему ваш сервер попадает в прокси-сервер? Это ваш сайт? Но в целом это имеет смысл - использование объекта, специфичного для запроса, во время специфического для приложения события может работать не слишком хорошо. Есть ли опасность в событии, связанном с запросом, например в событии жизненного цикла страницы (Page.LoadCompleted и т. Д.)? - person mlhDev; 16.10.2012
comment
Я не особо разбирался в том, почему он разрешается в proxyfire. Конечно, это был не мой сайт, но он показал мне, что Current.Request.Url не был на 100% надежным. После долгих исследований я также обнаружил, что динамическое определение вашего имени хоста непросто из-за нескольких сетевых карт, IP-адресов и доменных имен, которые разрешаются на один и тот же IP-адрес. Что касается вашего другого вопроса, Мэтт, я не уверен, что вы имеете в виду: ( - person Thirlan; 17.10.2012
comment
так это когда-либо происходило только в Application_BeginRequest? Я не понимаю, как IIS мог когда-либо отправить этот запрос в ваше приложение, если, возможно, у вас не установлен заголовок хоста? - person Simon_Weaver; 08.02.2013
comment
@Thirlan - я пытаюсь отладить проблему, похожую на эту. Я пытаюсь получить поддомен с помощью Request.Url.Host, и «обычно» работает хорошо, но не всегда. Есть ли что-нибудь вокруг этого? Как что-то еще в запросе, что может быть правильным? - person scojomodena; 12.11.2014
comment
В то время я много читал об этом, и, к сожалению, единственный надежный способ - это жестко запрограммировать. - person Thirlan; 18.11.2014

Почему бы не использовать

Request.Url.Authority

Он возвращает весь домен И порт.

Вам все равно нужно указать http или https

person Korayem    schedule 17.07.2011
comment
Это тоже работает. Чтобы указать http или https, просто поставьте перед ним //. Так, например, он будет читаться как href = // @ Request.Url.Authority ... - person EdwardM; 03.11.2016

Простой и короткий способ (поддерживает схему, домен и порт):

Используйте 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
person RAM    schedule 20.08.2017

По-другому:


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

Как насчет:

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"];
person Derek Lawless    schedule 15.09.2008

Использование 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();
person Darren    schedule 01.04.2015

В Asp.Net Core 3.1, если вы хотите получить полный домен, вам нужно сделать следующее:

Шаг 1. Определите переменную

private readonly IHttpContextAccessor _contextAccessor;

Шаг 2: DI в конструктор

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

Шаг 3: Добавьте этот метод в свой класс:

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
person Dastan Alybaev    schedule 20.09.2020

Как насчет:

String domain = "http://" + Request.Url.Host
person jwalkerjr    schedule 15.09.2008
comment
Неплохо, но что, если на вашем сайте есть защищенные страницы, например https: // Что делать, если ваш домен не размещен на порту 80? - person Matt Mitchell; 15.09.2008