วิธีใดที่ดีที่สุดใน 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 เช่น "/Folder/Content/filename.html" (พูดว่าสร้างโดย Url.RouteUrl () ใน ASP.NET MVC) ลงใน URL โดยตรงและควรใช้งานได้


3
โปรดทราบว่า "โดเมนปัจจุบัน" ในที่นี้คือสิ่งที่ User-agent ที่ใช้ในการเข้าถึงไซต์ของคุณซึ่งในหลาย ๆ กรณีจะแตกต่างจาก "URL ที่เป็นทางการ" ของไซต์ของคุณรวมถึงสิ่งที่ผู้ใช้ปลายทางอาจป้อนลงในเบราว์เซอร์ของตน ( พร็อกซีย้อนกลับพร็อกซีส่งต่อชื่อโฮสต์ภายในที่อยู่ IP ... )
bzlm

1
มีวิธีรับ "URL อย่างเป็นทางการ" (จาก IIS หรือไม่)
Matt Mitchell

คำตอบ:


186

คำตอบเดียวกับ MattMitchell แต่มีการปรับเปลี่ยนบางอย่าง ซึ่งจะตรวจสอบพอร์ตเริ่มต้นแทน

แก้ไข: อัปเดตไวยากรณ์และใช้Request.Url.Authorityตามที่แนะนำ

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

3
มีฟิลด์ที่กำหนด i .NET ที่ฉันสามารถใช้แทน ":" ได้หรือไม่ บางอย่างเช่น System.Uri.PortDelimiter? คุณรู้เพียงเพื่อความสม่ำเสมอ :)
Jan Aagaard

2
ไม่ใช่ว่าฉันรู้จัก Jan Aagaard แต่คุณสามารถสร้างมันขึ้นมาได้ตลอดเวลา ฉันทำเช่นนั้นสำหรับสตริงและตัวเลข "เวทมนตร์" ส่วนใหญ่ สำหรับเรื่องนั้นคุณจะใช้ string.Empty แทน "" ในคำตอบของ Carlos;)
vbullinger

8
คุณสามารถใช้Request.Url.Authorityเป็น Korayem ปัญหาแทนและRequest.Url.Host Request.Url.Port
Schmalls

4
แทนที่จะเชื่อมต่อสตริงคุณควรใช้คลาส System.UriBuilder
BrainSlugs83

3
@MattMitchell ดูเหมือนว่าจะไม่พบปัญหากับ Authority แต่เทียบเท่ากับ Host + ":" + Port ดูซอร์สโค้ดdotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe Romagnuolo

41

ตามลิงค์นี้จุดเริ่มต้นที่ดีคือ:

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ตามคำตอบที่ได้รับการยอมรับด้านบนจาก Carlos Muñoz


1
ทำไมสมมติว่าพอร์ต 80 ที่นี่? หากคุณลบข้อสันนิษฐานนั้นออกรหัสจะดูเหมือนรับทั้งหมด เมื่อคุณถือว่าพอร์ต 80 คุณจะล้มเหลวในหลาย ๆ สถานการณ์ (ดูความคิดเห็นเกี่ยวกับ anwers อื่น ๆ ) หากคุณต้องการลบหมายเลขพอร์ตออกหากเป็นไปได้คุณต้องตรวจสอบว่าหมายเลขพอร์ตเป็นค่าเริ่มต้นสำหรับโครงร่างที่เป็นปัญหาและโครงร่างรองรับหมายเลขพอร์ตเริ่มต้น
bzlm

โปรดทราบว่าพอร์ต 80 อาจเป็นความคิดที่ไม่ดี ฉันไม่รู้วิธีอื่นในเรื่องนี้แม้ว่าฉันจะพูดถึงเรื่องนี้ว่าจะต้องขึ้นอยู่กับการกำหนดค่า
Matt Mitchell

1
ฉันไม่รู้ว่าสิ่งนี้จะช่วยได้หรือไม่ แต่คุณสามารถลอง: หาก Request.IsSecureConnection เพื่อตรวจสอบว่ามีการใช้ HTTPS หรือไม่?
Erick Brown

1
@EricBrown - ใช่คำตอบนี้ไม่ดีใน retropsect 5 ปีต่อมา ฉันจะตอบรับคำตอบที่ยอมรับของ Carlos Muñozเพื่อหลีกเลี่ยงปัญหานั้น
Matt Mitchell


20

คำเตือน! สำหรับทุกคนที่ใช้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

ข้อบกพร่องนี้บังคับให้ฉันต้องแทรกโฮสต์โดเมนของฉันเป็นสตริงในไฟล์กำหนดค่า


ไม่เหมือนกันทุกประการ โดเมนของฉันอยู่ใน web.config ในขณะนี้
Korayem

ฉันคิดว่าฉันเข้าใจ - ทำไมเซิร์ฟเวอร์ของคุณถึงโดน proxyfire นั่นคือไซต์ของคุณหรือไม่ แต่โดยรวมแล้วการใช้ออบเจ็กต์เฉพาะคำขอระหว่างเหตุการณ์เฉพาะแอปพลิเคชันอาจทำงานได้ไม่ดีนัก มีอันตรายในเหตุการณ์เฉพาะคำขอเช่นเหตุการณ์วงจรชีวิตของเพจ (Page.LoadCompleted ฯลฯ ) หรือไม่
mlhDev

ฉันไม่ได้ตรวจสอบอย่างหนักว่าทำไมมันถึงแก้ไขเป็น proxyfire มันไม่ใช่ไซต์ของฉันอย่างแน่นอน แต่มันบ่งบอกให้ฉันทราบว่า Current.Request.Url ไม่น่าเชื่อถือ 100% หลังจากการวิจัยมากมายฉันได้ค้นพบว่าการกำหนดชื่อโฮสต์ของคุณแบบไดนามิกนั้นไม่ใช่เรื่องง่ายเนื่องจากมีการ์ด NIC หลายตัว IP และชื่อโดเมนที่แก้ไขเป็น IP เดียวกัน สำหรับคำถามอื่น ๆ ของคุณ Matt ฉันไม่แน่ใจว่าคุณหมายถึงอะไร: (
Thirlan

ดังนั้นสิ่งนี้เคยเกิดขึ้นใน Application_BeginRequest เท่านั้น? ฉันไม่เห็นว่า IIS จะส่งคำขอนี้ไปยังแอปของคุณได้อย่างไรเว้นแต่คุณจะไม่ได้ตั้งค่าส่วนหัวของโฮสต์ไว้
Simon_Weaver

@Thirlan - ฉันกำลังพยายามแก้ไขปัญหาที่ฟังดูคล้ายกับสิ่งนี้ ฉันพยายามรับโดเมนย่อยโดยใช้ Request.Url.Host และ 'ปกติ' จะทำงานได้ดี แต่ก็ไม่เสมอไป มีจริงหรือไม่? เหมือนอย่างอื่นในคำร้องที่อาจถูกต้อง?
scojomodena

14

ทำไมไม่ใช้

Request.Url.Authority

ส่งคืนโดเมนทั้งหมดและพอร์ต

คุณยังต้องคิด http หรือ https


2
นี่ก็ใช้ได้เหมือนกัน หากต้องการ "figure" 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.