Comment puis-je obtenir l'URL de base de mon application Web dans ASP.NET MVC?

300

Comment puis-je déterminer rapidement l'URL racine de mon application ASP.NET MVC? C'est-à-dire, si IIS est configuré pour servir mon application sur http://example.com/foo/bar , alors j'aimerais pouvoir obtenir cette URL de manière fiable, ce qui n'implique pas d'obtenir l'URL actuelle à partir du demander et le découper d'une manière fragile qui se brise si je réachemine mon action.

La raison pour laquelle j'ai besoin de l'URL de base est que cette application Web en appelle une autre qui a besoin de la racine de l'application Web de l'appelant à des fins de rappel.

Benjamin Pollack
la source

Réponses:

399

En supposant que vous disposez d'un objet Request, vous pouvez utiliser:

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

S'il n'est pas disponible, vous pouvez y accéder via le contexte:

var request = HttpContext.Current.Request
tghw
la source
8
Qu'est-ce que c'est urlHelper.Content("~")? Comment créer définir urlHelper? Merci!
Maxim Zaslavsky
31
@Maxim, vous pouvez probablement remplacer Url.Content ("~")
UpTheCreek
13
Ce que j'ai fini par utiliser: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
Pour MVC 4, j'utiliseControllerContext.RequestContext.HttpContext.Request
row1
7
@Url.Content("~")se résout en "/", qui n'est pas l'URL de base.
Andrew Hoffman
114

Donc, aucune de celles énumérées ici n'a fonctionné pour moi, mais en utilisant quelques-unes des réponses, j'ai obtenu que quelque chose fonctionne:

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

Mise à jour pour ASP.NET Core / MVC 6:

ASP.NET Corerend ce processus un peu plus pénible, surtout si vous êtes au fond de votre code. Vous avez 2 options pour accéder auHttpContext

1) Remettez-le depuis votre controller:

var model = new MyClass(HttpContext);

puis dans model:

private HttpContext currentContext;

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

2) Peut-être que la façon la plus propre est de l'injecter dans votre classe, ce qui commence par enregistrer les types dans votre Startup:

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

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

puis faites-le injecter pour vous comme ceci:

private HttpContext currentContext;

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

dans les deux cas, voici la mise à jour pour .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
la source
Où avez-vous mis cette méthode?
Josh Dean
3
Cela dépend vraiment de la fréquence à laquelle vous devez l'utiliser ... s'il s'agit d'un accord à usage unique, mettez-le simplement dans la classe où vous avez besoin de ces données, si vous prévoyez de l'utiliser dans plusieurs classes de votre application, alors j'utilise un dossier appelé Helpersdans la base de mon application, j'ai une staticclasse appelée Staticset je mets des fonctions comme ci - dessus là ... juste être sûr de vous faire changer ci - dessus à partir public string GetBaseUrl()depublic static string GetBaseUrl()
Serj Sagan
En tant que mise à jour, je n'utilise plus une classe appelée Statics, au lieu de cela, je l'ai divisée en utilisations plus spécifiques, donc dans ce cas, cela irait dans ma UrlHelperclasse
Serj Sagan
1
De toutes les options que j'ai trouvées, c'est la seule qui a réellement fonctionné pour moi. Votre # 2 c'est. Merci beaucoup!
adeldegan
2
J'ai voté pour cela parce que c'est le seul à mentionner PathBase, c'est exactement ce dont j'avais besoin. Merci!
Dave
69

Dans du code:

Url.Content("~/");

Syntaxe du rasoir MVC3:

@Url.Content("~/")
mxasim
la source
11
C'est très bien pour une utilisation sur les pages Razor, mais si vous essayez de passer l'URL à une source externe, cela ne vous donnera pas l'URL complète.
krillgar
5
Ça ne marche pas. Il va simplement ajouter /au lieu du nom réel.
Mrchief
2
Où est l' Urlaide de Code disponible dès le départ? Peut-être seulement dans le Controller. Certainement pas dans le ViewModelou tout autre classoù vous pourriez avoir besoin de cela ..
Serj Sagan
43

C'est peut-être une extension ou une modification des réponses publiées ici, mais j'utilise simplement la ligne suivante et cela fonctionne:

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

Quand mon chemin est: http://host/iis_foldername/controller/action
alors je reçois:http://host/iis_foldername/

Bronek
la source
26

L'extrait suivant fonctionne bien pour moi dans MVC4 et n'a pas besoin d'un HttpContextdisponible:

System.Web.HttpRuntime.AppDomainAppVirtualPath
user666142
la source
Semble également fonctionner dans MVC3. Je l'utilise jQuery.load()pour construire l'URL du contrôleur et l'action que je veux appeler: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe
pourquoi ferais-tu ça? au lieu d'appeler Url.Action?
BlackTigerX
4
Ne fonctionne pas lors du déploiement sur Azure. Les réponses les mieux notées fonctionnent dans ce scénario.
Jeff Dunlop
25

L'astuce pour s'appuyer sur IIS est que les liaisons IIS peuvent être différentes de vos URL publiques (WCF, je vous regarde), en particulier avec les machines de production multi-hébergées. J'ai tendance à utiliser la configuration pour définir explicitement l'url "de base" à des fins externes car cela a tendance à être un peu plus efficace que de l'extraire de l'objet Request.

Wyatt Barnett
la source
2
Également vrai pour les serveurs derrière les équilibreurs de charge ou les proxys.
Ishmaeel
20

Pour une URL de base absolue, utilisez ceci. Fonctionne avec HTTP et HTTPS.

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

Il s'agit d'une conversion d'une propriété asp.net en MVC . C'est une méthode à peu près tout en chantant et en dansant pour obtenir l'URL racine.

Déclarez une classe auxiliaire:

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

Usage:

Pour utiliser à partir d'un contrôleur:

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

Pour utiliser dans une vue:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)
Paul Zahra
la source
1
C'est la seule réponse qui explique la possibilité d'un site fonctionnant sur un port autre que 80. Toutes les autres réponses ne sont pas sûres en ce qui me concerne. Merci!
jebar8
12

Dans MVC _Layout.cshtml:

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

C'est ce que nous utilisons!

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
la source
+1 pour l'utilisation <base>. Vous pouvez également omettre le schéma de sorte qu'il fonctionne avec http ou https. Cela signifie que vous pouvez démarrer l'URL avec //.
Jess
5

Cela fonctionne bien pour moi (également avec un équilibreur de charge):

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

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

Surtout si vous utilisez des numéros de port non standard, l'utilisation de Request.Url.Authority apparaît comme une bonne piste au début, mais échoue dans un environnement LB.

Tadej Gregorcic
la source
3

Vous pouvez avoir une méthode statique qui examine HttpContext.Current et décide quelle URL utiliser (développement ou serveur en direct) en fonction de l'ID d'hôte. HttpContext pourrait même offrir un moyen plus facile de le faire, mais c'est la première option que j'ai trouvée et cela fonctionne bien.

Adrian Grigore
la source
3

Vous pouvez utiliser le script suivant en vue:

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

Pour ASP.NET MVC 4, c'est un peu différent:

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

Cela fonctionne dans ASP .NET MVC 4 Dans n'importe quelle action de contrôleur, vous pouvez écrire: 1stline obtient l'url entière + la chaîne de requête. La deuxième ligne supprime le chemin d'accès local et la requête, dernier symbole '/'. 3ème ligne, ajoutez le symbole «/» à la dernière position.

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

en html simple et ASP.NET ou ASP.NET MVC si vous utilisez la balise:

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

Pour une URL avec un alias d'application comme http://example.com/appAlias/ ... Vous pouvez essayer ceci:

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

Sur la page Web elle-même:

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

Dans le javascript:

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

Cela fonctionne pour mon projet MVC, j'espère que cela aide

Andrew Day
la source
@hemp Modifié mais n'a pas voté pour? J'espère que les points vous sont précieux
Andrew Day
Cette question et les réponses associées n'étaient pas utiles pour mon problème particulier, donc je n'ai essayé ni voté pour aucune d'entre elles. J'ai édité celui-ci parce que je l'ai vu et j'ai pensé que cela pourrait être une réponse décente s'il était formaté correctement. J'essaie juste d'être un bon citoyen.
chanvre
De plus, aucun point de réputation n'est obtenu pour l'édition d'une réponse.
chanvre
2

Je mets ça dans la tête de mon _Layout.cshtml

 <base href="~/" />
cineam mal orthographié
la source
2

C'est peut-être une meilleure solution.

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

en utilisant

<a href="@baseUrl" class="link">Base URL</a>
SP
la source
1
Je n'ai pas testé, mais je doute que cela fonctionne lorsque l'url de base est directement virtuelle. c'est à dire. localhost / myApp
emragins
1

Pour MVC 4:

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

Ce qui suit a fonctionné solidement pour moi

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
la source
1
@{
    var baseurl = Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + Url.Content("~");
}
@baseurl

--sortie http: // localhost: 49626 / TEST /

Jackdon Wang
la source
1

C'était ma solution (en utilisant .net core 3.1, dans un contrôleur api):

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

Obtenez simplement BaseUrl en une seule ligne

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

//output example: https://stackoverflow.com
Zahid Tanveer
la source
0

ajoutez cette fonction dans une classe statique dans un projet comme une classe utilitaire:

Contenu d' utilitaire.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;
    }
}

utilisez ce code n'importe où et profitez-en:

var baseUrl = Utility.GetBaseUrl();
DLMAN
la source