Wie kann ich die Basis-URL meiner Webanwendung in ASP.NET MVC abrufen?

300

Wie kann ich schnell feststellen, wie die Stamm-URL für meine ASP.NET MVC-Anwendung lautet? Das heißt, wenn IIS so eingestellt ist, dass es meine Anwendung unter http://example.com/foo/bar bereitstellt , möchte ich in der Lage sein, diese URL auf zuverlässige Weise abzurufen, ohne die aktuelle URL von der abzurufen fordern Sie es an und zerhacken Sie es auf eine fragile Art und Weise, die kaputt geht, wenn ich meine Aktion umleitung.

Der Grund, warum ich die Basis-URL benötige, ist, dass diese Webanwendung eine andere aufruft, die den Stamm der Anrufer-Webanwendung für Rückrufzwecke benötigt.

Benjamin Pollack
quelle

Antworten:

399

Angenommen, Sie haben ein Anforderungsobjekt zur Verfügung, können Sie Folgendes verwenden:

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

Wenn es nicht verfügbar ist, können Sie es über den Kontext aufrufen:

var request = HttpContext.Current.Request
tghw
quelle
8
Was ist urlHelper.Content("~")? Wie erstelle ich define urlHelper? Vielen Dank!
Maxim Zaslavsky
31
@ Maxim, können Sie wahrscheinlich Url.Content ("~")
UpTheCreek
13
Was ich letztendlich benutzt habe: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
Für MVC 4 benutze ichControllerContext.RequestContext.HttpContext.Request
row1
7
@Url.Content("~")wird aufgelöst zu "/", was nicht die Basis-URL ist.
Andrew Hoffman
114

Also hat keiner der hier aufgeführten für mich funktioniert, aber mit ein paar der Antworten habe ich etwas zum Laufen gebracht:

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

Update für ASP.NET Core / MVC 6:

ASP.NET Coremacht diesen Prozess etwas schmerzhafter, besonders wenn Sie tief in Ihrem Code sind. Sie haben 2 Möglichkeiten, um an derHttpContext

1) Geben Sie es von Ihrem controller:

var model = new MyClass(HttpContext);

dann in model:

private HttpContext currentContext;

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

2) Vielleicht ist der sauberere Weg, es in Ihre Klasse zu injizieren, was mit der Registrierung der Typen in Ihrer Klasse beginnt Startup:

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

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

dann lass es dir so spritzen:

private HttpContext currentContext;

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

In beiden Fällen ist hier die Aktualisierung für .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
quelle
Wo haben Sie diese Methode hingelegt?
Josh Dean
3
Das hängt wirklich davon ab, wie oft Sie es verwenden müssen. Wenn es sich um ein Einweggeschäft handelt, fügen Sie es einfach in die Klasse ein, in der Sie diese Daten benötigen. Wenn Sie damit rechnen, es in mehreren Klassen in Ihrer App zu verwenden, verwende ich a Ordner Helpersin der Basis meiner App staticaufgerufen , ich habe eine Klasse namens Staticsund ich habe Funktionen wie die oben genannten dort ... stellen Sie nur sicher, dass Sie die oben genannten von public string GetBaseUrl()in ändernpublic static string GetBaseUrl()
Serj Sagan
Als Update verwende ich keine Klasse mehr mit dem Namen Statics, sondern habe sie in spezifischere Verwendungen unterteilt. In diesem Fall würde dies in meine UrlHelperKlasse gehen
Serj Sagan
1
Von allen Optionen, die ich gefunden habe, ist dies die einzige, die tatsächlich für mich funktioniert hat. Deine Nummer 2 also. Vielen Dank!
Adeldegan
2
Ich habe dies positiv bewertet, weil es das einzige ist, das PathBase erwähnt, was genau das ist, was ich brauchte. Vielen Dank!
Dave
69

In Code:

Url.Content("~/");

MVC3 Razor Syntax:

@Url.Content("~/")
mxasim
quelle
11
Dies ist in Ordnung für die Verwendung auf den Razor-Seiten. Wenn Sie jedoch versuchen, die URL an eine externe Quelle zu übergeben, erhalten Sie nicht die vollständige URL.
Krillgar
5
Es funktioniert nicht. Es wird nur /anstelle des tatsächlichen Namens hinzugefügt .
Mrchief
2
Wo ist Code Url? Steht Ihnen der Helfer sofort zur Verfügung? Vielleicht nur in der Controller. Sicherlich nicht in dem ViewModeloder einem anderen, classwo Sie dies brauchen könnten.
Serj Sagan
43

Vielleicht ist es eine Erweiterung oder Änderung der hier veröffentlichten Antworten, aber ich benutze einfach die folgende Zeile und es funktioniert:

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

Wenn mein Weg ist: http://host/iis_foldername/controller/action
dann erhalte ich:http://host/iis_foldername/

Bronek
quelle
26

Das folgende Snippet funktioniert gut für mich in MVC4 und benötigt kein HttpContextverfügbares:

System.Web.HttpRuntime.AppDomainAppVirtualPath
user666142
quelle
Scheint auch in MVC3 zu funktionieren. Ich benutze es in jQuery.load(), um die URL für den Controller und die Aktion zu $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
erstellen, die
warum würdest du das tun? anstatt Url.Action aufzurufen?
BlackTigerX
4
Funktioniert nicht, wenn es in Azure bereitgestellt wird. Antworten mit höheren Bewertungen funktionieren in diesem Szenario.
Jeff Dunlop
25

Der Trick beim Verlassen auf IIS besteht darin, dass sich IIS-Bindungen von Ihren öffentlichen URLs (WCF, die ich Ihnen ansehe) unterscheiden können, insbesondere bei Produktionsmaschinen mit mehreren Standorten. Ich tendiere dazu, die Konfiguration zu verwenden, um die "Basis" -URL explizit für externe Zwecke zu definieren, da dies tendenziell etwas erfolgreicher ist als das Extrahieren aus dem Request-Objekt.

Wyatt Barnett
quelle
2
Dies gilt auch für Server hinter Load Balancern oder Proxys.
Ishmaeel
20

Verwenden Sie dies für eine absolute Basis-URL. Funktioniert sowohl mit HTTP als auch mit HTTPS.

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

Dies ist eine Konvertierung einer asp.net-Eigenschaft in MVC . Es ist so ziemlich alles, was singt und tanzt.

Deklarieren Sie eine Helferklasse:

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

Verwendungszweck:

So verwenden Sie eine Steuerung:

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

So verwenden Sie eine Ansicht:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)
Paul Zahra
quelle
1
Dies ist die einzige Antwort, die die Möglichkeit berücksichtigt, dass eine Site auf einem anderen Port als 80 ausgeführt wird. Alle anderen Antworten sind für mich unsicher. Vielen Dank!
Jebar8
12

In MVC _Layout.cshtml:

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

Das verwenden wir!

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
quelle
+1 für die Verwendung <base>. Sie können das Schema auch so weglassen, dass es mit http oder https funktioniert. Das heißt, Sie können die URL mit beginnen //.
Jess
5

Dies funktioniert gut für mich (auch mit einem Load Balancer):

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

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

Insbesondere wenn Sie nicht standardmäßige Portnummern verwenden, erscheint die Verwendung von Request.Url.Authority zunächst als guter Hinweis, schlägt jedoch in einer LB-Umgebung fehl.

Tadej Gregorcic
quelle
3

Sie könnten eine statische Methode haben, die HttpContext.Current betrachtet und abhängig von der Host-ID entscheidet, welche URL (Entwicklungs- oder Live-Server) verwendet werden soll. HttpContext bietet vielleicht sogar eine einfachere Möglichkeit, dies zu tun, aber dies ist die erste Option, die ich gefunden habe, und sie funktioniert einwandfrei.

Adrian Grigore
quelle
3

Sie können das folgende Skript in der Ansicht verwenden:

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

Für ASP.NET MVC 4 ist das etwas anders:

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

Dies funktioniert in ASP .NET MVC 4 In jeder Controller-Aktion, die Sie schreiben können: 1stline erhält die gesamte URL + Abfragezeichenfolge. 2. Zeile lokalen Pfad & Abfrage entfernen, letztes '/' Symbol. 3. Zeile '/' Symbol an letzter Stelle hinzufügen.

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

in einfachem HTML und ASP.NET oder ASP.NET MVC, wenn Sie Tag verwenden:

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

Für URLs mit Anwendungsalias wie http://example.com/appAlias/ ... Sie können dies versuchen:

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

Auf der Webseite selbst:

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

Im Javascript:

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

Das funktioniert für mein MVC-Projekt, hoffe es hilft

Andrew Day
quelle
@hemp Bearbeitet, aber nicht dafür gestimmt? Hoffe, die Punkte sind wertvoll für Sie
Andrew Day
Diese Frage und die damit verbundenen Antworten waren für mein spezielles Problem nicht hilfreich, daher habe ich nicht versucht, für eines von ihnen zu stimmen. Ich habe dieses bearbeitet, weil ich es zufällig gesehen habe und dachte, es wäre eine anständige Antwort, wenn es richtig formatiert wäre. Ich versuche nur, ein guter Bürger zu sein.
Hanf
Es gibt auch keine Reputationspunkte für die Bearbeitung einer Antwort.
Hanf
2

Ich habe dies in den Kopf meiner _Layout.cshtml eingefügt

 <base href="~/" />
cineam falsch geschrieben
quelle
2

Vielleicht ist es eine bessere Lösung.

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

mit

<a href="@baseUrl" class="link">Base URL</a>
MS
quelle
1
Ich habe nicht getestet, aber ich bezweifle, dass dies funktioniert, wenn die Basis-URL direkt virtuell ist. dh. localhost / myApp
emragins
1

Für MVC 4:

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

Das Folgende hat für mich solide funktioniert

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

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

Jackdon Wang
quelle
1

Dies war meine Lösung (mit .net Core 3.1 in einem API-Controller):

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

Einfach in einer Zeile BaseUrl erhalten

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

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

Fügen Sie diese Funktion in der statischen Klasse in einem Projekt wie der Utility-Klasse hinzu:

Dienstprogramm.cs Inhalt:

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

Verwenden Sie diesen Code überall und genießen Sie ihn:

var baseUrl = Utility.GetBaseUrl();
DLMAN
quelle