ASP.NET에서 현재 도메인을 얻는 가장 좋은 방법은 무엇입니까?


102

ASP.NET에서 현재 도메인을 얻는 가장 좋은 방법이 무엇인지 궁금합니다.

예를 들면 :

http://www.domainname.com/subdir/ 은 http://www.domainname.com 을 산출해야합니다 . http://www.sub.domainname.com/subdir/ 은 http://sub.domainname.com 을 산출해야합니다 .

가이드로 "/Folder/Content/filename.html"(ASP.NET MVC에서 Url.RouteUrl ()에 의해 생성 된 것처럼)과 같은 URL을 URL에 바로 추가 할 수 있어야하며 제대로 작동해야합니다.


3
여기에서 "현재 도메인"은 실제로 귀하의 사이트에 접속하는 데 사용되는 소비 사용자 에이전트이며, 대부분의 경우 귀하의 사이트의 "공식 URL"및 최종 사용자가 브라우저에 입력 한 내용과 다릅니다 ( 역방향 프록시, 정방향 프록시, 내부 호스트 이름, IP 주소 등).
— bzlm

1
"공식 URL"(IIS에서 가져온 URL)을 얻는 방법이 있습니까?
— Matt Mitchell

답변:


186

MattMitchell과 같은 대답이지만 약간의 수정이 있습니다. 대신 기본 포트를 확인합니다.

편집 : 업데이트 된 구문 및 Request.Url.Authority제안 된대로 사용

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

3
":"대신 사용할 수있는 필드가 .NET에 정의되어 있습니까? System.Uri.PortDelimiter와 같은 것? 일관성을 위해. :)
— Jan Aagaard

2
내가 아는 건 아니지만 Jan Aagaard는 항상 현지에서 만들 수 있습니다. 나는 대부분의 "마법"문자열과 숫자에 대해 그렇게합니다. 그 문제에 대해서는 Carlos '대답에서 ""대신 string.Empty를 사용합니다.)
— vbullinger

8
및 Request.Url.Authority대신 Korayem이 제안한대로 사용할 수 있습니다 . Request.Url.HostRequest.Url.Port
— Schmalls

4
문자열을 연결하는 대신 System.UriBuilder 클래스를 사용해야합니다.
— BrainSlugs83

3
@MattMitchell, Authority와 관련된 문제를 발견하지 못한 것 같습니다. Host + ":"+ Port와 동일합니다. 소스 코드 참조 dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
— Giuseppe 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은 구성에 따라 다릅니다.

따라서 Carlos Muñoz의 위 IsDefaultPort의 Accepted Answer 에서 와 같이 사용해야합니다 .


1
여기서 포트 80을 가정하는 이유는 무엇입니까? 이 가정을 제거하면 코드가 포괄적 인 것처럼 보입니다. 포트 80을 가정하면 많은 시나리오에서 실패합니다 (다른 응답에 대한 설명 참조). 가능한 경우 포트 번호를 제거하려면 포트 번호가 해당 체계의 기본값이고 체계가 기본 포트 번호를 지원하는지 확인해야합니다.
— bzlm

예, 포트 80은 나쁜 생각 일 수 있습니다. 나는 이것에 대한 다른 방법을 모르기 때문에 구성에 의존해야한다고 언급했습니다.
— Matt Mitchell

1
이것이 도움이 될지 모르겠지만 HTTPS가 사용되는지 여부를 결정하기 위해 Request.IsSecureConnection을 시도해 볼 수도 있습니다.
— Erick Brown

1
@EricBrown-예,이 답변은 5 년 후 retropsect에서 좋지 않습니다. 나는 그 문제를 피하기 위해 Carlos Muñoz의 대답을 받아 들일 것입니다.
— Matt Mitchell

29
Request.Url.GetLeftPart(UriPartial.Authority)

이것은 포함 된 계획입니다.


23
그들이 그 이름과 함께 왔을 때 나는 회의에 있었던 싶어요
— Simon_Weaver

20

경고! Current.Request .Url.Host 를 사용하는 모든 사람에게 . CURRENT REQUEST를 기반으로 작업하고 있으며 현재 요청이 항상 서버에 있지 않으며 때로는 다른 서버에있을 수 있음을 이해하십시오.

따라서 Global.asax의 Application_BeginRequest ()와 같이 이것을 사용하면 99.9 %는 괜찮지 만 0.1 %는 서버의 호스트 이름이 아닌 다른 것을 얻을 수 있습니다.

이에 대한 좋은 예는 얼마 전에 발견 한 것입니다. 내 서버는 때때로 http://proxyjudge1.proxyfire.net/fastenv 를 누르는 경향이 있습니다. Application_BeginRequest ()는이 요청을 기꺼이 처리하므로이 요청을 할 때 Request.Url.Host를 호출하면 proxyjudge1.proxyfire.net을 다시 받게됩니다. 여러분 중 일부는 "no duh"라고 생각할 수도 있지만 0.1 %의 시간 동안 만 발생했기 때문에 알아 차리기가 매우 어려운 버그 였기 때문에 주목할 가치가 있습니다. P

이 버그로 인해 구성 파일에 내 도메인 호스트를 문자열로 삽입해야했습니다.


정확히 똑 같았습니다. 내 도메인은 이제 web.config에 있습니다.
— Korayem 2011

내가 생각하는 이유는 서버 히트 proxyfire을한다 -하지만, 내가 이해? 귀하의 사이트입니까? 그러나 전반적으로 의미가 있습니다. 응용 프로그램 별 이벤트 중에 요청 별 개체를 사용하면 제대로 작동하지 않을 수 있습니다. 페이지 수명주기 이벤트 (Page.LoadCompleted 등)와 같은 요청 별 이벤트에 위험이 있습니까?
— mlhDev 2010 년

나는 그것이 왜 프록시 파이어를 해결했는지에 대해 너무 열심히 조사하지 않았습니다. 확실히 내 사이트는 아니지만 Current.Request.Url이 100 % 신뢰할 수 없다는 것을 나타냅니다. 많은 연구 끝에 동일한 IP로 확인되는 여러 NIC 카드, IP 및 도메인 이름으로 인해 호스트 이름을 동적으로 결정하는 것이 쉽지 않음을 발견했습니다. 다른 질문 Matt에 관해서는, 무슨 뜻인지 잘 모르겠습니다. (
— Thirlan

그래서 이것은 Application_BeginRequest에서만 발생합니까? 호스트 헤더가 설정되어 있지 않으면 IIS가 어떻게이 요청을 앱에 보낼 수 있었는지 모르겠습니다.
— Simon_Weaver 2013

@Thirlan-이와 비슷한 소리가 나는 문제를 디버깅하려고합니다. Request.Url.Host를 사용하여 하위 도메인을 얻으려고하는데 '보통'이 잘 작동하지만 항상 그런 것은 아닙니다. 이 주위에 정말로 있는가? 요청의 다른 내용이 정확할 수 있습니까?
— scojomodena

14

사용하지 않는 이유

Request.Url.Authority

전체 도메인과 포트를 반환합니다.

여전히 http 또는 https를 계산해야합니다.


2
이것도 작동합니다. http 또는 https를 "그림"하려면 앞에 "//"를 넣으십시오. 예를 들어 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에서 호스팅되지 않으면 어떻게됩니까?
— Matt Mitchell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.