Come posso ottenere l'URL di base della mia webapp in ASP.NET MVC?


300

Come posso determinare rapidamente qual è l'URL radice per la mia applicazione MVC ASP.NET? Vale a dire, se IIS è impostato per servire la mia applicazione su http://example.com/foo/bar , mi piacerebbe essere in grado di ottenere quell'URL in un modo affidabile che non implichi ottenere l'URL corrente dal richiesta e troncandolo in qualche modo fragile che si rompe se reindirizzo la mia azione.

Il motivo per cui ho bisogno dell'URL di base è che questa applicazione Web ne chiama un'altra che ha bisogno del root per l'applicazione Web del chiamante ai fini della richiamata.

Risposte:


399

Supponendo che tu abbia un oggetto Request disponibile, puoi usare:

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

Se non è disponibile, puoi accedervi tramite il contesto:

var request = HttpContext.Current.Request

8
Che cosa è urlHelper.Content("~")? Come creo definisci urlHelper? Grazie!
Maxim Zaslavsky,

31
@Maxim, probabilmente puoi sostituire Url.Content ("~")
UpTheCreek

13
Cosa ho finito per usare: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
Per MVC 4 usoControllerContext.RequestContext.HttpContext.Request
row1

7
@Url.Content("~")si risolve in "/", che non è l'URL di base.
Andrew Hoffman,

114

Quindi nessuno di quelli elencati qui ha funzionato per me, ma usando alcune delle risposte, ho ottenuto qualcosa che funzionava:

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;
}

Aggiornamento per ASP.NET Core / MVC 6:

ASP.NET Corerende questo processo un po 'più doloroso, specialmente se sei profondamente nel tuo codice. Hai 2 opzioni per accedere alHttpContext

1) Passalo dal tuo controller:

var model = new MyClass(HttpContext);

quindi in model:

private HttpContext currentContext;

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

2) Forse il modo più pulito è iniettarlo nella tua classe, che inizia con la registrazione dei tipi nella tua Startup:

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

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

allora ti viene iniettato in questo modo:

private HttpContext currentContext;

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

in entrambi i casi, ecco l'aggiornamento per .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}";
}

Dove hai messo questo metodo?
Josh Dean,

3
Dipende molto dalla frequenza con cui devi usarlo ... se si tratta di un affare monouso, inseriscilo nella classe in cui hai bisogno di questi dati, se prevedi di usarlo in più classi nella tua app, allora uso un cartella chiamata Helpersnella base della mia app, ho una staticclasse chiamata Staticse ho inserito funzioni come quelle sopra ... assicurati di cambiare da sopra public string GetBaseUrl()apublic static string GetBaseUrl()
Serj Sagan,

Come aggiornamento, non uso più una classe chiamata Statics, invece l'ho suddivisa in usi più specifici, quindi in questo caso andrebbe nella mia UrlHelperclasse
Serj Sagan,

1
Di tutte le opzioni che ho trovato, questa è l'unica che ha funzionato per me. Il tuo numero 2 che è. Grazie mille!
Adeldegan,

2
Ha valutato questo perché è l'unico a menzionare PathBase, che è esattamente quello di cui avevo bisogno. Grazie!
Dave,

69

Nel codice:

Url.Content("~/");

Sintassi del rasoio MVC3:

@Url.Content("~/")

11
Questo va bene per l'utilizzo sulle pagine Razor, ma se stai provando a passare l'URL a una fonte esterna, non ti darà l'URL completo.
Krillgar,

5
Non funziona Aggiungerà semplicemente /invece del nome reale.
Mrchief,

2
Dov'è Code l' Urlhelper a tua disposizione fin dall'inizio? Forse solo nel Controller. Certamente non nel ViewModelo in nessun altro classdove potresti aver bisogno di questo ...
Serj Sagan,

43

Forse è l'estensione o la modifica delle risposte pubblicate qui ma io uso semplicemente la seguente riga e funziona:

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

Quando il mio percorso è: http://host/iis_foldername/controller/action
quindi ricevo:http://host/iis_foldername/


26

Il seguente frammento funziona bene per me in MVC4 e non ha bisogno di un HttpContextdisponibile:

System.Web.HttpRuntime.AppDomainAppVirtualPath

Sembra funzionare anche in MVC3. Lo uso jQuery.load()per costruire l'URL per il controller e l'azione che voglio chiamare: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe,

Perché dovresti farlo? invece di chiamare Url.Action?
BlackTigerX,

4
Non funziona se distribuito in Azure. Le risposte più votate funzionano in questo scenario.
Jeff Dunlop,

25

Il trucco di fare affidamento su IIS è che i collegamenti IIS possono essere diversi dai tuoi URL pubblici (WCF ti sto guardando), specialmente con macchine di produzione multi-homed. Tendo a utilizzare la configurazione per definire esplicitamente l'URL "base" per scopi esterni, poiché tende ad avere un po 'più successo rispetto all'estrazione dall'oggetto Request.


2
Vero anche per server dietro bilanciamento del carico o proxy.
Ismaele

20

Per un URL di base assoluto utilizzare questo. Funziona con HTTP e HTTPS.

new Uri(Request.Url, Url.Content("~"))

15

Questa è una conversione di una proprietà asp.net in MVC . È praticamente tutto cantando tutto ballando ottenere il metodo url di root.

Dichiarare una classe di supporto:

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;
        }
    }
}

Uso:

Per utilizzare da un controller:

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

Per utilizzare in una vista:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
Questa è l'unica risposta che spiega la possibilità di un sito in esecuzione su un porto diverso da 80. Tutte le altre risposte non sono sicure per quanto mi riguarda. Grazie!
jebar8

12

In MVC _Layout.cshtml:

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

Questo è quello che usiamo!

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("~/");
        }
}

+1 per l'utilizzo <base>. Inoltre puoi omettere lo Schema in modo che funzioni con http o https. Ciò significa che puoi iniziare l'URL con //.
Jess,

5

Questo funziona bene per me (anche con un bilanciamento del carico):

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

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

Soprattutto se si utilizzano numeri di porta non standard, l'utilizzo di Request.Url.Authority appare inizialmente come un buon vantaggio, ma non riesce in un ambiente LB.


3

Potresti avere un metodo statico che esamina HttpContext.Current e decide quale URL utilizzare (server di sviluppo o live) in base all'ID host. HttpContext potrebbe anche offrire un modo più semplice per farlo, ma questa è la prima opzione che ho trovato e funziona bene.


3

È possibile utilizzare il seguente script in vista:

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

3

Per ASP.NET MVC 4 è un po 'diverso:

string url = HttpContext.Request.Url.AbsoluteUri;

3

Questo funziona in ASP .NET MVC 4 In qualsiasi azione del controller puoi scrivere: 1stline ottiene l'intero url + Query String. 2a riga rimuove percorso e query locali, ultimo simbolo '/'. La terza riga aggiunge il simbolo '/' all'ultima posizione.

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

3

in html semplice e ASP.NET o ASP.NET MVC se si utilizza il tag:

<a href="~/#about">About us</a>

3

Per l'URL con alias di applicazione come http://example.com/appAlias/ ... Puoi provare questo:

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

3

Sulla stessa pagina Web:

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

Nel javascript:

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

Questo funziona per il mio progetto MVC, spero che sia d'aiuto


@hemp Lo ha modificato ma non lo hai votato? Spero che i punti siano preziosi per te
Andrew Day

Questa domanda e le risposte associate non sono state utili per il mio problema specifico, quindi non ho provato a votare per nessuna di esse. Ho modificato questo perché mi è capitato di vederlo e ho pensato che potesse essere una risposta decente se fosse formattato correttamente. Sto solo cercando di essere un buon cittadino.
canapa

Inoltre, non ci sono punti reputazione guadagnati per la modifica di una risposta.
canapa


2

Forse è una soluzione migliore.

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

utilizzando

<a href="@baseUrl" class="link">Base URL</a>

1
Non ho testato, ma dubito che funzionerà quando l'URL di base è direttamente virtuale. vale a dire. localhost / myApp
emragins

1

Per MVC 4:

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

1

Quanto segue ha funzionato perfettamente per me

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");


1

Questa era la mia soluzione (utilizzando .net core 3.1, in un controller api):

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

0

Semplicemente in una riga ottieni BaseUrl

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

//output example: https://stackoverflow.com


0

aggiungi questa funzione nella classe statica nel progetto come la classe di utilità:

contenuto 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;
    }
}

usa questo codice ovunque e divertiti:

var baseUrl = Utility.GetBaseUrl();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.