Bagaimana saya bisa mendapatkan URL basis webapp saya di ASP.NET MVC?

300

Bagaimana saya bisa dengan cepat menentukan apa URL root untuk aplikasi ASP.NET MVC saya? Yaitu, jika IIS diatur untuk melayani aplikasi saya di http://example.com/foo/bar , maka saya ingin bisa mendapatkan URL itu dengan cara yang andal yang tidak melibatkan mendapatkan URL saat ini dari meminta dan memotongnya dalam beberapa cara rapuh yang rusak jika saya mengubah rute tindakan saya.

Alasan saya memerlukan URL dasar adalah bahwa aplikasi web ini memanggil yang lain yang membutuhkan root untuk aplikasi web pemanggil untuk keperluan panggilan balik.

Benjamin Pollack
sumber

Jawaban:

399

Dengan asumsi Anda memiliki objek Permintaan yang tersedia, Anda dapat menggunakan:

string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

Jika tidak tersedia, Anda bisa mendapatkannya melalui konteks:

var request = HttpContext.Current.Request
tghw
sumber
8
Apa urlHelper.Content("~")? Bagaimana cara membuat define urlHelper? Terima kasih!
Maxim Zaslavsky
31
@ Maxim, Anda bisa mengganti Url.Content ("~")
UpTheCreek
13
Apa yang akhirnya saya gunakan:var request = HttpContext.Current.Request; urlBase = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, (new System.Web.Mvc.UrlHelper(request.RequestContext)).Content("~"));
Peter
7
Untuk MVC 4 saya menggunakanControllerContext.RequestContext.HttpContext.Request
row1
7
@Url.Content("~")memutuskan untuk "/", yang bukan url dasar.
Andrew Hoffman
114

Jadi tidak ada yang tercantum di sini yang berfungsi untuk saya, tetapi menggunakan beberapa jawaban, saya dapat sesuatu yang berhasil:

public string GetBaseUrl()
{
    var request = HttpContext.Current.Request;
    var appUrl = HttpRuntime.AppDomainAppVirtualPath;

    if (appUrl != "/") 
        appUrl = "/" + appUrl;

    var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);

    return baseUrl;
}

Pembaruan untuk ASP.NET Core / MVC 6:

ASP.NET Coremembuat proses ini sedikit lebih menyakitkan, terutama jika Anda tenggelam dalam kode Anda. Anda memiliki 2 opsi untuk mendapatkannya diHttpContext

1) Serahkan dari controller:

var model = new MyClass(HttpContext);

lalu di model:

private HttpContext currentContext;

public MyClass(HttpContext currentContext)
{
    this.currentContext = currentContext;
}

2) Mungkin cara yang lebih bersih adalah dengan menyuntikkannya ke kelas Anda, yang dimulai dengan mendaftarkan jenis di Anda Startup:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<MyClass, MyClass>();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

kemudian disuntikkan untuk Anda seperti ini:

private HttpContext currentContext;

public MyClass(IHttpContextAccessor httpContextAccessor)
{
    currentContext = httpContextAccessor.HttpContext;
}

dalam kedua kasus, berikut adalah pembaruan untuk .NET Core GetBaseUrl():

public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

    return $"{request.Scheme}://{host}{pathBase}";
}
Serj Sagan
sumber
Di mana Anda meletakkan metode ini?
Josh Dean
3
Itu benar-benar tergantung pada seberapa sering Anda perlu menggunakannya ... jika ini adalah satu perjanjian penggunaan maka letakkan saja di kelas di mana Anda memerlukan data ini, jika Anda mengantisipasi menggunakannya di beberapa kelas di aplikasi Anda, maka saya menggunakan folder yang disebut Helpersdi dasar aplikasi saya, saya memiliki statickelas yang disebut Staticsdan saya meletakkan fungsi seperti di atas sana ... pastikan Anda mengubah di atas dari public string GetBaseUrl()kepublic static string GetBaseUrl()
Serj Sagan
Sebagai pemutakhiran, saya tidak lagi menggunakan kelas yang dipanggil Statics, sebaliknya saya memecahnya menjadi penggunaan yang lebih spesifik, jadi dalam hal ini akan masuk ke UrlHelperkelas saya
Serj Sagan
1
Dari semua opsi yang saya temukan, ini adalah satu-satunya yang benar-benar bekerja untuk saya. # 2 kamu itu. Terima kasih banyak!
adeldegan
2
Terpilih ini karena itu satu-satunya yang menyebutkan PathBase, yang persis apa yang saya butuhkan. Terima kasih!
Dave
69

Dalam kode:

Url.Content("~/");

Sintaks Razor MVC3:

@Url.Content("~/")
mxasim
sumber
11
Ini bagus untuk digunakan pada halaman Razor, tetapi jika Anda mencoba meneruskan URL ke sumber eksternal, itu tidak akan memberi Anda URL lengkap.
krillgar
5
Itu tidak bekerja. Itu hanya akan menambahkan /bukan nama sebenarnya.
Mrchief
2
Di mana Kode apakah Urlpembantu tersedia untuk Anda langsung? Mungkin hanya di Controller. Tentu saja tidak di ViewModelatau di classmana pun Anda mungkin memerlukan ini ..
Serj Sagan
43

Mungkin ekstensi atau modifikasi dari jawaban yang diposting di sini, tetapi saya hanya menggunakan baris berikut dan berfungsi:

Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")

Ketika jalur saya adalah: http://host/iis_foldername/controller/action
maka saya menerima:http://host/iis_foldername/

Bronek
sumber
26

Cuplikan berikut ini berfungsi dengan baik untuk saya di MVC4, dan tidak perlu HttpContexttersedia:

System.Web.HttpRuntime.AppDomainAppVirtualPath
pengguna666142
sumber
Tampaknya bekerja di MVC3 juga. Saya menggunakannya jQuery.load()untuk membuat URL untuk pengontrol dan tindakan yang ingin saya panggil: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe
Kenapa kamu ingin melakukan itu? alih-alih memanggil Url.Action?
BlackTigerX
4
Tidak berfungsi saat digunakan untuk Azure. Jawaban yang berperingkat lebih tinggi berfungsi dalam skenario ini.
Jeff Dunlop
25

Trik dengan mengandalkan IIS adalah bahwa ikatan IIS dapat berbeda dari URL publik Anda (WCF saya melihat Anda), terutama dengan mesin produksi multi-homed. Saya cenderung vektor ke arah menggunakan konfigurasi untuk secara eksplisit mendefinisikan url "base" untuk keperluan eksternal karena itu cenderung sedikit lebih berhasil daripada mengekstraknya dari objek Request.

Wyatt Barnett
sumber
2
Juga berlaku untuk server di belakang load balancers atau proxy.
Ishmaeel
20

Untuk URL basis absolut, gunakan ini. Bekerja dengan HTTP dan HTTPS.

new Uri(Request.Url, Url.Content("~"))
arni
sumber
15

Ini adalah konversi properti asp.net ke MVC . Ini hampir semua bernyanyi semua menari mendapatkan metode url root.

Nyatakan kelas pembantu:

namespace MyTestProject.Helpers
{
    using System.Web;

    public static class PathHelper
    {
        public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
        {
            string appPath = string.Empty;

            if (httpRequestBase != null)
            {
                //Formatting the fully qualified website url/name
                appPath = string.Format("{0}://{1}{2}{3}",
                            httpRequestBase.Url.Scheme,
                            httpRequestBase.Url.Host,
                            httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
                            httpRequestBase.ApplicationPath);
            }

            if (!appPath.EndsWith("/"))
            {
                appPath += "/";
            }

            return appPath;
        }
    }
}

Pemakaian:

Untuk digunakan dari pengontrol:

PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)

Untuk digunakan dalam tampilan:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)
Paul Zahra
sumber
1
Ini adalah satu-satunya jawaban yang menjelaskan kemungkinan situs berjalan pada port selain 80. Semua jawaban lain tidak aman sejauh yang saya ketahui. Terima kasih!
jebar8
12

Di MVC _Layout.cshtml:

<base href="@Request.GetBaseUrl()" />

Itulah yang kami gunakan!

public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
        {
          if (request.Url == (Uri) null)
            return string.Empty;
          else
            return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
        }
}
Katibaer
sumber
+1 untuk digunakan <base>. Anda juga dapat menghilangkan Skema sehingga akan berfungsi dengan http atau https. Itu berarti Anda dapat memulai url dengan //.
Jess
5

Ini berfungsi baik untuk saya (juga dengan penyeimbang beban):

@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content(“~”);
}

<script>
    var base_url = "@baseurl";
</script>

Terutama jika Anda menggunakan nomor port non-standar, menggunakan Request.Url. Otoritas tampak seperti petunjuk yang baik pada awalnya, tetapi gagal dalam lingkungan LB.

Tadej Gregorcic
sumber
3

Anda bisa memiliki metode statis yang terlihat di HttpContext.Current dan memutuskan URL mana yang akan digunakan (pengembangan atau server langsung) tergantung pada ID host. HttpContext bahkan mungkin menawarkan beberapa cara yang lebih mudah untuk melakukannya, tetapi ini adalah opsi pertama yang saya temukan dan berfungsi dengan baik.

Adrian Grigore
sumber
3

Anda dapat menggunakan skrip berikut dalam tampilan:

<script type="text/javascript">
    var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>
Andrus
sumber
3

Untuk ASP.NET MVC 4 agak berbeda:

string url = HttpContext.Request.Url.AbsoluteUri;
Fernando Vezzali
sumber
3

Ini bekerja di ASP .NET MVC 4 Dalam setiap tindakan pengontrol Anda dapat menulis: 1stline mendapatkan seluruh url + String Kueri. Baris ke-2 menghapus lintasan & kueri lokal, simbol '/' terakhir. Baris ketiga tambahkan simbol '/' di posisi terakhir.

Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );
Muhammad Ashikuzzaman
sumber
3

dalam html sederhana dan ASP.NET atau ASP.NET MVC jika Anda menggunakan tag:

<a href="~/#about">About us</a>
Ravi Anand
sumber
3

Untuk url dengan alias aplikasi seperti http://example.com/appAlias/ ... Anda dapat mencoba ini:

var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);
Jacek Gzel
sumber
3

Di halaman web itu sendiri:

<input type="hidden" id="basePath" value="@string.Format("{0}://{1}{2}",
  HttpContext.Current.Request.Url.Scheme,
  HttpContext.Current.Request.Url.Authority,
  Url.Content("~"))" />

Dalam javascript:

function getReportFormGeneratorPath() {
  var formPath = $('#reportForm').attr('action');
  var newPath = $("#basePath").val() + formPath;
  return newPath;
}

Ini berfungsi untuk proyek MVC saya, semoga membantu

Andrew Day
sumber
@hemp Diedit tetapi tidak memilihnya? Semoga poinnya berharga bagi Anda
Andrew Day
Pertanyaan ini dan jawaban yang terkait tidak membantu untuk masalah khusus saya jadi saya tidak mencoba atau memilih salah satu dari mereka. Saya mengedit yang ini karena saya kebetulan melihatnya dan berpikir itu mungkin jawaban yang layak jika diformat dengan benar. Hanya berusaha menjadi warga negara yang baik.
rami,
Juga, tidak ada poin reputasi yang diperoleh untuk mengedit jawaban.
rami
2

Saya menempatkan ini di kepala _Layout.cshtml saya

 <base href="~/" />
Cineam salah eja
sumber
2

Mungkin itu solusi yang lebih baik.

@{
   var baseUrl = @Request.Host("/");
}

menggunakan

<a href="@baseUrl" class="link">Base URL</a>
MS
sumber
1
Saya tidak menguji, tetapi saya ragu ini akan berfungsi ketika basis url adalah virtual langsung. yaitu. localhost / myApp
emragins
1

Untuk MVC 4:

String.Format("{0}://{1}{2}", Url.Request.RequestUri.Scheme, Url.Request.RequestUri.Authority, ControllerContext.Configuration.VirtualPathRoot);
Remigijus Pankevičius
sumber
1

Berikut ini berhasil bagi saya

var request = HttpContext.Request;
                        var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;

                        if (appUrl != "/")
                            appUrl = "/" + appUrl + "/";

                        var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");
venu
sumber
1
@{
    var baseurl = Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + Url.Content("~");
}
@baseurl

--output http: // localhost: 49626 / TEST /

Jackdon Wang
sumber
1

Ini adalah solusi saya (menggunakan .net core 3.1, dalam pengendali api):

string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";
Barnebyte
sumber
0

Cukup dalam satu baris, dapatkan BaseUrl

string baseUrl = new Uri(Request.Url, Url.Content("~")).AbsoluteUri;

//output example: https://stackoverflow.com
Zahid Tanveer
sumber
0

tambahkan fungsi ini di kelas statis dalam proyek seperti kelas utilitas:

konten utility.cs :

public static class Utility
{
    public static string GetBaseUrl()
    {
        var request = HttpContext.Current.Request;
        var urlHelper = new UrlHelper(request.RequestContext);
        var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
        return baseUrl;
    }
}

gunakan kode ini di mana saja dan nikmati:

var baseUrl = Utility.GetBaseUrl();
DLMAN
sumber