Apa metode terbaik di ASP.NET untuk mendapatkan domain saat ini?

102

Saya bertanya-tanya apa cara terbaik untuk mendapatkan domain saat ini di ASP.NET?

Misalnya:

http://www.domainname.com/subdir/ harus menghasilkan http://www.domainname.com http://www.sub.domainname.com/subdir/ harus menghasilkan http://sub.domainname.com

Sebagai panduan, saya harus dapat menambahkan url seperti "/Folder/Content/filename.html" (katakanlah seperti yang dihasilkan oleh Url.RouteUrl () di ASP.NET MVC) langsung ke URL dan seharusnya berfungsi.

Matt Mitchell
sumber
3
Perhatikan bahwa "domain saat ini" di sini sebenarnya adalah apa yang digunakan agen-pengguna yang menggunakan untuk sampai ke situs Anda, yang dalam banyak kasus berbeda dari "URL resmi" situs Anda serta apa yang mungkin dimasukkan pengguna akhir ke dalam browser mereka ( proxy terbalik, proxy penerusan, nama host internal, alamat IP, ...).
bzlm
1
Jadi, apakah ada cara untuk mendapatkan "URL resmi" (yang dari IIS?)
Matt Mitchell

Jawaban:

186

Jawaban yang sama dengan MattMitchell tetapi dengan beberapa modifikasi. Ini memeriksa port default sebagai gantinya.

Edit: Sintaks yang diperbarui dan gunakan Request.Url.Authorityseperti yang disarankan

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
Carlos Muñoz
sumber
3
Apakah ada bidang yang ditentukan i .NET, yang dapat saya gunakan sebagai ganti ":"? Sesuatu seperti System.Uri.PortDelimiter? Anda tahu, hanya untuk konsistensi. :)
Jan Aagaard
2
Setahu saya, Jan Aagaard, tapi Anda selalu bisa membuatnya secara lokal. Saya melakukannya untuk sebagian besar string dan angka "ajaib". Untuk masalah ini, Anda kemudian akan menggunakan string.Empty daripada "" dalam jawaban Carlos;)
vbullinger
8
Anda dapat menggunakan Request.Url.Authorityseperti yang disarankan Korayem daripada Request.Url.Hostdan Request.Url.Port.
Schmalls
4
Alih-alih menggabungkan string, Anda harus menggunakan kelas System.UriBuilder.
BrainSlugs83
3
@MattMitchell, tampaknya tidak menemukan masalah dengan Otoritas, ini setara dengan Host + ":" + Port, lihat kode sumber dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe Romagnuolo
40

Sesuai tautan ini, titik awal yang baik adalah:

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

Namun, jika domainnya adalah http://www.domainname.com:500 ini akan gagal.

Sesuatu seperti berikut ini menggoda untuk menyelesaikannya:

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

Namun, port 80 dan 443 akan bergantung pada konfigurasi.

Karena itu, Anda harus menggunakan IsDefaultPortseperti dalam Jawaban yang Diterima di atas dari Carlos Muñoz.

Matt Mitchell
sumber
1
Mengapa menganggap port 80 di sini? Jika Anda menghapus asumsi itu, kodenya tampak seperti penampung-semua. Ketika Anda menganggap port 80, Anda akan gagal dalam banyak skenario (lihat komentar di jawaban lain). Jika Anda ingin menghapus nomor port jika memungkinkan, Anda harus memeriksa bahwa nomor port adalah default untuk skema yang dimaksud, dan bahwa skema tersebut mendukung nomor port default.
bzlm
Ya lihat catatan bahwa port 80 mungkin ide yang buruk. Saya tidak tahu cara lain untuk mengatasi ini, itulah sebabnya saya menyebutkan itu perlu bergantung pada konfigurasi.
Matt Mitchell
1
Saya tidak tahu apakah ini akan membantu atau tidak, tetapi Anda juga dapat mencoba: apakah Request.IsSecureConnection untuk menentukan apakah HTTPS digunakan atau tidak?
Erick Brown
1
@EricBrown - Ya, jawaban ini tidak bagus dalam retropsect 5 tahun kemudian. Saya akan mengikuti jawaban yang diterima Carlos Muñoz untuk menghindari masalah itu.
Matt Mitchell
29
Request.Url.GetLeftPart(UriPartial.Authority)

Ini termasuk skema.

izlence
sumber
23
Saya ingin sekali berada dalam pertemuan ketika mereka datang dengan nama itu
Simon_Weaver
20

PERINGATAN! Kepada siapa saja yang menggunakan Current.Request .Url.Host. Pahami bahwa Anda bekerja berdasarkan PERMINTAAN SAAT INI dan bahwa permintaan saat ini tidak akan SELALU berada di server Anda dan terkadang dapat berada di server lain.

Jadi jika Anda menggunakan ini di sesuatu seperti, Application_BeginRequest () di Global.asax, maka 99,9% dari waktu itu akan baik-baik saja, tetapi 0,1% Anda mungkin mendapatkan sesuatu selain nama host server Anda sendiri.

Contoh bagus tentang ini adalah sesuatu yang saya temukan belum lama ini. Server saya cenderung menekan http://proxyjudge1.proxyfire.net/fastenv dari waktu ke waktu. Application_BeginRequest () dengan senang hati menangani permintaan ini jadi jika Anda memanggil Request.Url.Host saat membuat permintaan ini, Anda akan mendapatkan kembali proxyjudge1.proxyfire.net. Beberapa dari Anda mungkin berpikir "no duh" tetapi perlu diperhatikan karena ini adalah bug yang sangat sulit untuk diperhatikan karena hanya terjadi 0,1% dari waktu: P

Bug ini memaksa saya untuk memasukkan host domain saya sebagai string di file konfigurasi.

Thirlan
sumber
Melakukan hal yang persis sama. Domain saya sekarang ada di web.config.
Korayem
Saya rasa saya mengerti - mengapa server Anda terkena proxyfire? Apakah itu situs Anda? Tapi, secara keseluruhan, masuk akal - menggunakan objek khusus permintaan selama acara khusus aplikasi mungkin tidak berfungsi dengan baik. Apakah ada bahaya dalam peristiwa khusus permintaan, seperti peristiwa siklus hidup halaman (Page.LoadCompleted, dll.)?
mlhDev
Saya tidak menyelidiki terlalu keras mengapa itu memutuskan untuk proxyfire. Itu jelas bukan situs saya, tetapi itu menunjukkan kepada saya bahwa Current.Request.Url tidak 100% dapat diandalkan. Setelah banyak penelitian, saya juga menemukan bahwa menentukan nama host Anda secara dinamis tidaklah mudah, karena beberapa kartu NIC, IP, dan nama domain yang menyelesaikan ke IP yang sama. Adapun pertanyaan Anda yang lain Matt, saya tidak yakin apa yang Anda maksud: (
Thirlan
jadi ini hanya terjadi di Application_BeginRequest? Saya tidak melihat bagaimana IIS bisa mengirim permintaan ini ke aplikasi Anda kecuali Anda mungkin tidak menyetel header host?
Simon_Weaver
@Thirlan - Saya mencoba men-debug masalah yang kedengarannya mirip dengan ini. Saya mencoba untuk mendapatkan subdomain menggunakan Request.Url.Host dan 'biasanya' berfungsi dengan baik, tetapi tidak selalu. Benarkah ada di sekitar ini? Seperti hal lain dalam permintaan yang mungkin benar?
scojomodena
14

Mengapa tidak digunakan

Request.Url.Authority

Ini mengembalikan seluruh domain DAN port.

Anda masih perlu mencari http atau https

Korayem
sumber
2
Ini juga berhasil. Untuk "mencari" http atau https, letakkan "//" di depannya. Jadi misalnya akan terbaca sebagai href = "// @ Request.Url.Authority ..."
EdwardM
2

Cara sederhana dan singkat (mendukung skema, domain dan port):

Menggunakan 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
RAM
sumber
1

Cara lain:


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

sumber
Jawaban sederhana namun cukup mengagumkan!
Shiroy
1

Bagaimana tentang:

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"];
Derek Lawless
sumber
0

Menggunakan 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
sumber
-1

Bagaimana tentang:

String domain = "http://" + Request.Url.Host
jwalkerjr
sumber
Lumayan, tapi bagaimana jika situs Anda memiliki halaman aman yaitu https: // Bagaimana jika domain Anda tidak di-host pada port 80?
Matt Mitchell