Uzyskaj surowy adres URL z Microsoft.AspNet.Http.HttpRequest

87

HttpRequestKlasa w Asp.Net 5 (vNext) zawiera (między innymi) analizowanych Szczegółowe informacje na temat URL żądania, takie jak Scheme, Host, Pathitp

Nie zauważyłem jeszcze nigdzie, co ujawnia pierwotny adres URL żądania - tylko te przeanalizowane wartości. (W poprzednich wersjach było Request.Uri)

Czy mogę odzyskać surowy adres URL bez konieczności składania go razem z komponentów dostępnych w HttpRequest?

Jon Egerton
źródło
1
Wydaje się, że błąd został zgłoszony wcześniej w tej sprawie, ale został zamknięty ... prawdopodobnie możesz sprawdzić szczegóły, a jeśli czujesz się silniejszy, możesz zaktualizować go o szczegóły: github.com/aspnet/HttpAbstractions/issues/110
Kiran Challa
@KiranChalla: W pewnym sensie rozumiem ich punkt widzenia, chociaż prowadzi mnie to do zastanowienia się, czym jest RawURL w poprzednich wersjach. Wydaje mi się, że to, co obecnie pokazują na temat schematu, hosta itp., Można odgadnąć od obsługi żądania po stronie serwera, a nie niczego w samym żądaniu.
Jon Egerton
czy próbowałeś ToString ()?
agua z marca

Odpowiedzi:

82

Wygląda na to, że nie możesz uzyskać do niego bezpośredniego dostępu, ale możesz go zbudować za pomocą frameworka:

Microsoft.AspNetCore.Http.Extensions.UriHelper.GetFullUrl(Request)

Możesz również użyć powyższego jako metody rozszerzenia.

To zwraca stringraczej niż a Uri, ale powinno służyć temu celowi! (Wydaje się, że to również spełnia rolę UriBuilder.)

Dzięki @mswietlicki za wskazanie, że został on po prostu refaktoryzowany, a nie brakujący! A także do @CF, aby wskazać zmianę przestrzeni nazw w mojej odpowiedzi!

Matt DeKrey
źródło
4
To już nie działa od wersji beta-5. Nie mam dobrej alternatywy lub zaktualizowałbym moją odpowiedź.
Matt DeKrey
13
Uważam, że jest to prawdziwa metoda rozszerzająca - po prostu importujesz przestrzeń nazw i wywołujesz albo GetEncodedUrilub GetDisplayUri, w zależności od przypadku użycia.
dlras2
42
using Microsoft.AspNet.Http.Extensions; i to Request.GetDisplayUrl ()
mswietlicki
8
Właściwa przestrzeń nazw to teraz Microsoft.AspNetCore.Http.Extensions
CF
9
W przypadku ASP.NET Core 1,0 dodaj przy użyciu „Microsoft.AspNetCore.Http.Extensions” do widoku Razor. Aby uzyskać adres URL, użyj „@ Context.Request.GetDisplayUrl ()”.
Joop
75

Dodaj pakiet Nuget / używając:

using Microsoft.AspNetCore.Http.Extensions; 

(W ASP.NET Core RC1 było to w Microsoft.AspNet.Http.Extensions)

wtedy możesz uzyskać pełny adres URL żądania http, wykonując:

var url = httpContext.Request.GetEncodedUrl();

lub

var url = httpContext.Request.GetDisplayUrl();

w zależności od celów.

Velin Georgiev
źródło
Czy ASP.NET Core RC2 jest już dostępny?
Sergey G.
Patrząc na źródło, wyraźnie wykonują one pewne kodowanie / dekodowanie, więc nie będzie to surowy adres URL. Ponadto usługi IIS czasami zmieniają adres URL, zanim dotrze do Kestrel, np.% 2F -> /.
Daniel Leach,
1
@TomStickel Nie jestem pewien, o czym mówisz ... Nie miałem problemu z używaniem żadnego z nich. Upewnij się, że masz usingdyrektywę w swoim pliku, tak jak opisano w odpowiedzi, ponieważ nie są to „normalne” metody, ale raczej metody rozszerzające.
Nick Mertin
1
@TomStickel fair. Zwracam tylko uwagę, że z pakietem Microsoft.AspNetCore.All zainstalowanym dla ASP.NET Core 2.2 (również testowanym w wersji 2.0), działa to dobrze.
Nick Mertin
16

Jeśli naprawdę chcesz mieć rzeczywisty, surowy adres URL , możesz użyć następującej metody rozszerzenia:

public static class HttpRequestExtensions
{
    public static Uri GetRawUrl(this HttpRequest request)
    {
        var httpContext = request.HttpContext;

        var requestFeature = httpContext.Features.Get<IHttpRequestFeature>();

        return new Uri(requestFeature.RawTarget);
    }
}

Ta metoda wykorzystuje RawTargetżądanie, które nie jest wyświetlane w samym HttpRequestobiekcie. Ta właściwość została dodana w wersji 1.0.0 programu ASP.NET Core. Upewnij się, że używasz tej lub nowszej wersji.

UWAGA! Ta właściwość ujawnia nieprzetworzony adres URL, więc nie został on zdekodowany, zgodnie z dokumentacją:

Ta właściwość nie jest używana wewnętrznie do podejmowania decyzji dotyczących routingu lub autoryzacji. Nie został on UrlDecoded i należy zachować ostrożność podczas jego używania.

khellang
źródło
Używam programu ASP .NET Core z pełnym .NET Framework. Wydaje się, że RawTargetto nie działa dla mnie ( nie jest zdefiniowane IHttpRequestFeature). Czy możesz wymyślić alternatywę?
Tomáš Hübelbauer
1
RawTargetzostał dodany w wersji 1.0, jeszcze w maju . Czy na pewno używasz najnowszej wersji?
khellang
1
W przypadku hostingu przy użyciu usług IIS usługi IIS czasami zmieniają adres URL, zanim dotrze do Kestrel. Jednym z przykładów jest to, że% 2F zostaje zdekodowany do /.
Daniel Leach,
To zdecydowanie miarodajna odpowiedź.
Chris Marisic
Wydaje się, że podaje ścieżkę adresu URL, a nie cały adres URL
Iain Ballard
10

W maszynce do golenia .NET Core:

@using Microsoft.AspNetCore.Http.Extensions
@Context.Request.GetEncodedUrl() //Use for any purpose (encoded for safe automation)

Możesz także użyć zamiast drugiej linii:

@Context.Request.GetDisplayUrl() //Use to display the URL only
Shadi Namrouti
źródło
8

Inne rozwiązania nie pasowały do ​​moich potrzeb, ponieważ chciałem bezpośrednio URIobiekt i myślę, że lepiej jest unikać łączenia ciągów (również) w tym przypadku, więc stworzyłem te metody rozszerzające niż użycie a UriBuilderi działa również z adresami URL takimi jak http://localhost:2050:

public static Uri GetUri(this HttpRequest request)
{
    var uriBuilder = new UriBuilder
    {
        Scheme = request.Scheme,
        Host = request.Host.Host,
        Port = request.Host.Port.GetValueOrDefault(80),
        Path = request.Path.ToString(),
        Query = request.QueryString.ToString()
    };
    return uriBuilder.Uri;
}
giammin
źródło
1
Dobry. Poprawiłem również Twoje rozwiązanie o opcjonalne parametry. Dlatego mogę kontrolować, którą część URI chcę odzyskać. Na przykład tylko host lub pełna ścieżka bez ciągu zapytania itp.
user3172616
@ user3172616 fajny pomysł!
giammin
1
(80)powinno być (-1). Jeśli masz schemat https z pominięciem portu w nagłówku "Host", wygeneruje to zły Uri (np. https://myweb:80/Z (-1)nim będzie https://myweb).
Igor Dražić
4

Następująca metoda rozszerzenia odtwarza logikę z wersji pre-beta5 UriHelper:

public static string RawUrl(this HttpRequest request) {
    if (string.IsNullOrEmpty(request.Scheme)) {
        throw new InvalidOperationException("Missing Scheme");
    }
    if (!request.Host.HasValue) {
        throw new InvalidOperationException("Missing Host");
    }
    string path = (request.PathBase.HasValue || request.Path.HasValue) ? (request.PathBase + request.Path).ToString() : "/";
    return request.Scheme + "://" + request.Host + path + request.QueryString;
}
Sam
źródło
3

To rozszerzenie działa dla mnie:

using Microsoft.AspNetCore.Http;

    public static class HttpRequestExtensions
    {
        public static string GetRawUrl(this HttpRequest request)
        {
            var httpContext = request.HttpContext;
            return $"{httpContext.Request.Scheme}://{httpContext.Request.Host}{httpContext.Request.Path}{httpContext.Request.QueryString}";
        }
    }
Mark Redman
źródło
0

W ASP.NET 5 beta5:

Microsoft.AspNet.Http.Extensions.UriHelper.Encode(
    request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString);
Bystre dziecko
źródło