Jak mogę uzyskać podstawowy adres URL mojej aplikacji internetowej w ASP.NET MVC?


300

Jak mogę szybko ustalić, jaki jest główny adres URL mojej aplikacji ASP.NET MVC? To znaczy, jeśli IIS jest skonfigurowany do obsługi mojej aplikacji pod adresem http://example.com/foo/bar , to chciałbym móc uzyskać ten adres URL w niezawodny sposób, który nie wymaga pobierania bieżącego adresu URL z prośbę i posiekaj ją w delikatny sposób, który zepsuje się, jeśli zmienię trasę.

Powodem, dla którego potrzebuję podstawowego adresu URL, jest to, że ta aplikacja internetowa wywołuje inną, która potrzebuje katalogu głównego do aplikacji internetowej dzwoniącego do celów wywołania zwrotnego.

Odpowiedzi:


399

Zakładając, że masz dostępny obiekt żądania, możesz użyć:

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

Jeśli nie jest dostępny, możesz do niego dotrzeć poprzez kontekst:

var request = HttpContext.Current.Request

8
Co to jest urlHelper.Content("~")? Jak utworzyć zdefiniować urlHelper? Dzięki!
Maxim Zaslavsky,

31
@Maxim, możesz prawdopodobnie zastąpić Url.Content ("~")
UpTheCreek

13
Co skończyło się na użyciu: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
Do MVC 4 używamControllerContext.RequestContext.HttpContext.Request
wiersz 1

7
@Url.Content("~")rozwiązuje na "/", który nie jest podstawowym adresem URL.
Andrew Hoffman

114

Więc żaden z wymienionych tutaj nie działał dla mnie, ale korzystając z kilku odpowiedzi, dostałem coś działającego:

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

Aktualizacja dla ASP.NET Core / MVC 6:

ASP.NET Coresprawia, że ​​ten proces jest nieco bardziej bolesny, szczególnie jeśli jesteś głęboko w kodzie. Masz 2 opcje, aby uzyskać dostęp doHttpContext

1) Przekaż go ze swojego controller:

var model = new MyClass(HttpContext);

następnie w model:

private HttpContext currentContext;

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

2) Być może najprostszym sposobem jest wstrzyknięcie go do twojej klasy, co zaczyna się od zarejestrowania typów w twoim Startup:

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

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

następnie wstrzyknij to dla ciebie w ten sposób:

private HttpContext currentContext;

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

w obu przypadkach zaktualizowano dla .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}";
}

Gdzie umieściłeś tę metodę?
Josh Dean

3
To naprawdę zależy od tego, jak często musisz go używać ... jeśli jest to umowa jednorazowego użytku, po prostu umieść ją w klasie, w której potrzebujesz tych danych, jeśli przewidujesz użycie jej w wielu klasach w Twojej aplikacji, to używam folder wywoływany Helpersw bazie mojej aplikacji, mam staticklasę o nazwie Staticsi umieszczam tam funkcje takie jak wyżej ... tylko upewnij się, że zmieniłeś powyższe z public string GetBaseUrl()napublic static string GetBaseUrl()
Serj Sagan

Jako aktualizację, nie używam już klasy o nazwie Statics, zamiast tego podzieliłem ją na bardziej konkretne zastosowania, więc w tym przypadku trafiłoby to do mojej UrlHelperklasy
Serj Sagan

1
Ze wszystkich opcji, które znalazłem, jest to jedyna, która faktycznie działała dla mnie. To jest twój numer 2. Wielkie dzięki!
adeldegan

2
Poprosiłem o to, ponieważ jako jedyny wspomniał o PathBase, a dokładnie tego potrzebowałem. Dzięki!
Dave

69

W kodzie:

Url.Content("~/");

Składnia Razor MVC3:

@Url.Content("~/")

11
Jest to przydatne do używania na stronach Razor, ale jeśli próbujesz przekazać adres URL do zewnętrznego źródła, nie da ci pełnego adresu URL.
krillgar

5
To nie działa Po prostu doda /zamiast rzeczywistej nazwy.
Mrchief

2
Gdzie jest Code, w którym Urlpomocnik jest dostępny od samego początku? Może tylko w Controller. Na pewno nie w ViewModelżadnym innym classmiejscu, w którym możesz tego potrzebować.
Serj Sagan

43

Może jest to rozszerzenie lub modyfikacja zamieszczonych tutaj odpowiedzi, ale używam po prostu następującego wiersza i działa:

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

Kiedy moja ścieżka to: http://host/iis_foldername/controller/action
wtedy otrzymuję:http://host/iis_foldername/


26

Poniższy fragment kodu działa dobrze w MVC4 i nie wymaga HttpContextdostępnego:

System.Web.HttpRuntime.AppDomainAppVirtualPath

Wydaje się również działać w MVC3. Używam go jQuery.load()do konstruowania adresu URL kontrolera i działania, które chcę wywołać: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe,

dlaczego chcesz to zrobić? zamiast dzwonić na Url.Action?
BlackTigerX,

4
Nie działa po wdrożeniu na platformie Azure. W tym scenariuszu działają odpowiedzi lepiej ocenione.
Jeff Dunlop

25

Sztuka polegania na IIS polega na tym, że powiązania IIS mogą różnić się od twoich publicznych adresów URL (WCF patrzę na ciebie), szczególnie w przypadku maszyn produkcyjnych z wieloma bazami. Skłaniam się do użycia konfiguracji w celu jawnego zdefiniowania „podstawowego” adresu URL do celów zewnętrznych, ponieważ jest to zwykle bardziej skuteczne niż wyodrębnienie go z obiektu Request.


2
Dotyczy to również serwerów równoważących obciążenie lub serwerów proxy.
Ishmaeel

20

Użyj bezwzględnego podstawowego adresu URL. Działa zarówno z HTTP, jak i HTTPS.

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

15

To jest konwersja właściwości asp.net do MVC . Prawie wszystko polega na śpiewaniu i tańczeniu metodą root root.

Zadeklaruj klasę pomocnika:

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

Stosowanie:

Aby użyć z kontrolera:

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

Aby użyć w widoku:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
To jedyna odpowiedź, która uwzględnia możliwość działania witryny na porcie innym niż 80. O ile mi wiadomo, wszystkie pozostałe odpowiedzi są niebezpieczne. Dzięki!
jebar8

12

W MVC _Layout.cshtml:

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

Tego używamy!

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 za użycie <base>. Możesz także pominąć Schemat tak, aby działał z http lub https. Oznacza to, że możesz zacząć od adresu URL //.
Jess

5

Działa to dla mnie dobrze (także w przypadku modułu równoważenia obciążenia):

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

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

Zwłaszcza jeśli używasz niestandardowych numerów portów, użycie Request.Url.Authority na początku wydaje się być dobrym tropem, ale kończy się niepowodzeniem w środowisku LB.


3

Możesz mieć metodę statyczną, która sprawdza HttpContext.Current i decyduje, którego adresu URL użyć (serwer programistyczny lub serwer na żywo) w zależności od identyfikatora hosta. HttpContext może nawet oferować łatwiejszy sposób na zrobienie tego, ale jest to pierwsza opcja, którą znalazłem i działa dobrze.


3

Możesz użyć następującego skryptu w widoku:

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


3

Działa to w ASP .NET MVC 4 W każdej akcji kontrolera, którą możesz napisać: 1stline pobiera cały adres URL + ciąg zapytania. Druga linia usuwa lokalną ścieżkę i zapytanie, ostatni symbol „/”. W trzecim wierszu dodaj symbol „/” na ostatniej pozycji.

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

3

w prostym HTML i ASP.NET lub ASP.NET MVC, jeśli używasz znacznika:

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

3

W przypadku adresu URL z aliasem aplikacji, takim jak http://example.com/appAlias/ ... Możesz spróbować:

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

3

Na samej stronie:

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

W javascript:

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

Działa to w moim projekcie MVC, mam nadzieję, że to pomoże


@hemp Edytowałeś to, ale nie głosowałeś na to? Mam nadzieję, że punkty te są dla ciebie cenne
Andrew Day

To pytanie i powiązane z nim odpowiedzi nie były pomocne w mojej konkretnej sprawie, więc nie próbowałem ani nie głosowałem na żadne z nich. Zredagowałem ten, ponieważ zdarzyło mi się go zobaczyć i pomyślałem, że może być przyzwoitą odpowiedzią, jeśli został poprawnie sformatowany. Staram się być dobrym obywatelem.
konopie

Ponadto nie ma punktów reputacji za edycję odpowiedzi.
konopie


2

Może to lepsze rozwiązanie.

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

za pomocą

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

1
Nie testowałem, ale wątpię, aby to zadziałało, gdy podstawowy adres URL jest wirtualny bezpośrednio. to znaczy. localhost / myApp
emragins

1

W przypadku MVC 4:

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

1

Poniższe działało dla mnie solidnie

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

To było moje rozwiązanie (przy użyciu .net core 3.1, w kontrolerze API):

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

0

Wystarczy w jednej linii uzyskać BaseUrl

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

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


0

dodaj tę funkcję do klasy statycznej w projekcie, takiej jak klasa narzędziowa:

zawartość 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;
    }
}

użyj tego kodu w dowolnym miejscu i ciesz się nim:

var baseUrl = Utility.GetBaseUrl();
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.