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.

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

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

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

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/


26

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

System.Web.HttpRuntime.AppDomainAppVirtualPath

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.


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

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)

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

+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.


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.


3

Vous pouvez utiliser le script suivant en vue:

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

3

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

string url = HttpContext.Request.Url.AbsoluteUri;

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

3

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

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

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

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


@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

C'est peut-être une meilleure solution.

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

en utilisant

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

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

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


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

0

Obtenez simplement BaseUrl en une seule ligne

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

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


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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.