Получить необработанный URL-адрес из Microsoft.AspNet.Http.HttpRequest

87

HttpRequestКласс в Asp.Net 5 (vNext) содержит (помимо всего прочего) разбираемой подробной информации о URL для запроса, таких как Scheme, Host, и Pathт.д.

Я еще не обнаружил нигде, открывающей исходный URL-адрес запроса - только эти проанализированные значения. (В предыдущих версиях было Request.Uri)

Могу ли я вернуть необработанный URL-адрес, не собирая его из компонентов, доступных в HttpRequest?

Джон Эгертон
источник
1
Похоже, что об этом ранее сообщалось об ошибке, но она закрыта ... вы, вероятно, можете проверить подробности этого, и, если вы чувствуете себя сильнее, возможно, обновите его подробностями: github.com/aspnet/HttpAbstractions/issues/110
Kiran Challa
@KiranChalla: Я как бы понимаю их точку зрения, хотя это заставляет меня задаться вопросом, что такое RawURL в предыдущих версиях. Я предполагаю, что то, что они показывают в настоящее время о схеме, хосте и т. Д., Можно определить по обработке запроса на стороне сервера, а не по самому запросу.
Джон Эгертон,
вы пробовали ToString ()?
Агуа от марта

Ответы:

82

Похоже, вы не можете получить к нему доступ напрямую, но вы можете создать его с помощью фреймворка:

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

Вы также можете использовать вышеуказанное как метод расширения.

Это возвращает a, stringа не a Uri, но это должно служить цели! (Похоже, это тоже играет роль UriBuilder.)

Спасибо @mswietlicki за то, что он просто отремонтирован, а не отсутствует! А также @CF, чтобы указать на изменение пространства имен в моем ответе!

Мэтт ДеКрей
источник
4
Это больше не работает с бета-5. У меня нет хорошей альтернативы, и я бы обновил свой ответ.
Мэтт Декри
13
Я считаю, что это был настоящий метод расширения - вы просто импортируете пространство имен и вызываете либо GetEncodedUriили GetDisplayUri, в зависимости от вашего варианта использования.
dlras2
42
с использованием Microsoft.AspNet.Http.Extensions; и этот Request.GetDisplayUrl ()
mswietlicki
8
Правильное пространство имен теперь Microsoft.AspNetCore.Http.Extensions
CF
9
Для ASP.NET Core 1.0 добавьте использование Microsoft.AspNetCore.Http.Extensions в представление Razor. Чтобы получить URL-адрес, используйте «@ Context.Request.GetDisplayUrl ()».
Joop
75

Добавьте пакет Nuget / используя:

using Microsoft.AspNetCore.Http.Extensions; 

(В ASP.NET Core RC1 это было в Microsoft.AspNet.Http.Extensions)

тогда вы можете получить полный URL-адрес http-запроса, выполнив:

var url = httpContext.Request.GetEncodedUrl();

или

var url = httpContext.Request.GetDisplayUrl();

в зависимости от целей.

Велин Георгиев
источник
Доступен ли сейчас ASP.NET Core RC2?
Сергей Григорьевич
Да - blogs.msdn.microsoft.com/webdev/2016/05/16/…
Велин Георгиев
Глядя на источник, они явно выполняют некоторую кодировку / декодирование, поэтому это не будет исходный URL-адрес. Кроме того, IIS иногда меняет URL-адрес до того, как он попадает в Kestrel, например% 2F -> /.
Дэниел Лич
1
@TomStickel Не уверен, о чем вы говорите ... У меня не было проблем с их использованием. Убедитесь, что usingв вашем файле есть директива, как описано в ответе, поскольку это не «обычные» методы, а, скорее, методы расширения.
Ник Мертин
1
Ярмарка @TomStickel. Просто отмечу, что с пакетом Microsoft.AspNetCore.All, установленным для ASP.NET Core 2.2 (также протестирован на 2.0), это отлично работает для меня.
Ник Мертин
16

Если вам действительно нужен фактический необработанный URL-адрес , вы можете использовать следующий метод расширения:

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

Этот метод использует RawTargetзапрос, который не отображается в самом HttpRequestобъекте. Это свойство было добавлено в версии 1.0.0 ASP.NET Core. Убедитесь, что вы используете эту или более новую версию.

НОТА! Это свойство предоставляет необработанный URL-адрес, поэтому он не был декодирован, как указано в документации:

Это свойство не используется внутри для решений маршрутизации или авторизации. Он не был закодирован по URL-адресу, и его следует использовать осторожно.

Khellang
источник
Я использую ASP .NET Core с полной .NET Framework. Похоже, это не работает для меня ( RawTargetне определено IHttpRequestFeature). Вы можете придумать альтернативу?
Tomáš Hübelbauer
1
RawTargetбыл добавлен в выпуск 1.0 еще в мае . Вы уверены, что используете последнюю версию?
khellang
1
При хостинге с использованием IIS IIS иногда меняет URL-адрес до того, как он попадет в Kestrel. Один из примеров этого -% 2F декодируется в /.
Дэниел Лич
Это, безусловно, авторитетный ответ.
Крис Марисич
Похоже, что это указывает путь URL, а не весь URL
Иэн Баллард,
10

В бритве .NET Core:

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

Вы также можете использовать вместо второй строки:

@Context.Request.GetDisplayUrl() //Use to display the URL only
Шади Намрути
источник
8

Другие решения не соответствовали моим потребностям, потому что я хотел напрямую URIобъект, и я думаю, что в этом случае лучше избегать конкатенации строк (также), поэтому я создал эти методы расширения, чем использовать a, UriBuilderи работает также с URL-адресами, например 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;
}
Джаммин
источник
1
Хороший. Также я улучшил ваше решение дополнительными параметрами. Поэтому я могу контролировать, какую часть URI я хочу вернуть. Например, только хост или полный путь без строки запроса и т. Д.
user3172616
@ user3172616 хорошая идея!
giammin
1
(80)должно быть (-1). Если у вас есть https-схема с опущенным портом в заголовке "Host", это будет генерировать неправильный Uri (например https://myweb:80/, с (-1)ним будет https://myweb).
Игорь Дражич
4

Следующий метод расширения воспроизводит логику из предварительной бета-версии5 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;
}
Сэм
источник
3

У меня работает это расширение:

с использованием 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}";
        }
    }
Марк Редман
источник
0

В ASP.NET 5 beta5:

Microsoft.AspNet.Http.Extensions.UriHelper.Encode(
    request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString);
Сообразительный ребенок
источник