Получение данных запроса. Работа с HttpRequest

При разработке web-приложений в ASP.NET Core важно знать, какой именно запрос осуществляет пользователь. Как минимум нам необходимо знать по какому пути отправлен запрос, какой HTTP-метод был использован (GET, POST, PUT и т.д.). Эти и другие свойства запроса содержаться в свойстве HttpRequest объекта HttpContext о котором пойдет речь далее.

Вначале рассмотрим, какие свойства предоставляет нам HttpRequest.

Свойства HttpRequest

У объекта HttpRequest определены следующие свойства:

Body Возвращает или задает текст запроса в виде Stream.
BodyReader Возвращает объект типа PipeReader для чтения запроса .
ContentLength Возвращает или задает заголовок Content-Length.
ContentType Возвращает или задает заголовок Content-Type.
Cookies Возвращает коллекцию cookie для данного запроса.
Form Возвращает или задает текст запроса в виде формы.
HasFormContentType Проверяет заголовок Content-Type на наличие типов форм.
Headers Возвращает заголовки запроса.
Host Возвращает или задает заголовок хоста. Это свойство может включать порт.
HttpContext Возвращает объект HttpContext, ассоциируемый с данным запросом.
IsHttps Возвращает значение true, если параметр RequestScheme имеет значение https.
Method Возвращает или задает HTTP-метод.
Path Возвращает или задает часть пути запроса, которая идентифицирует запрошенный ресурс.
PathBase Возвращает или задает базовый путь для запроса. Базовый путь, при этом, не должен заканчиваться косой чертой.
Protocol Возвращает или задает протокол запроса (например, HTTP/1.1).
Query Возвращает коллекцию параметров запроса, полученную из строки Request.QueryString.
QueryString Возвращает или задает необработанную строку запроса, используемую для создания коллекции запросов в Request.Query.
RouteValues Возвращает коллекцию значений маршрута для этого запроса.
Scheme Возвращает или задает схему HTTP-запроса.

 

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

Схема URL

Теперь рассмотрим несколько практических моментов работу с объектом HttpRequest.

Как получить заголовки запроса в ASP.NET Core?

Если нас интересуют абсолютно все заголовки запроса, то можно их прочитать, перебрав все пары «ключ-значение» из коллекции Headers, например, так:

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.Run(async context =>
        {
            //читаем все заголовки запроса
            foreach (var header in context.Request.Headers) 
            {
                await context.Response.WriteAsync($"{header.Key}: {header.Value} \r\n");    
            }
            
        });
        app.Run();
    }
}

Результат будет выглядеть следующим образом:

Чтение заголовков запроса ASP.NET Core

Если нас интересуют какие-то конкретные заголовки, то в этом случае мы можем:

1.Воспользоваться одноименным свойством у Headers, если это один из стандартных заголовков.  Например, получим значение заголовка Accept:

var acceptValue = context.Request.Headers.Accept.ToString();
await context.Response.WriteAsync(acceptValue);

2. Если заголовок не стандартный, то можем попробовать найти такой заголовок по его названию. Например,

var fetchDest = context.Request.Headers["sec-fetch-dest"];
await context.Response.WriteAsync(fetchDest.ToString());

Как получить путь запроса в ASP.NET Core?

Путь запроса (см. на схеме выше компонент PATH) позволяет понять какой ресурс запрашивает пользователь и, исходя из этого выстроить логику работы приложения. Например, путь /date может означать, что пользователь запрашивает текущую дату, а путь /user— что пользователь запрашивает список пользователей.

Для получения пути запроса у объекта HttpRequest в ASP.NET Core используется свойство Path. Например, пусть наше приложение будет содержать следующую логику:

  1. если путь запроса пустой, то выводим пользователю приветствие
  2. если путь запроса /date — выводим текущую дату на сервере
  3. если путь запроса /time — выводим текущее время на сервере
  4. если путь запроса не соответствует ни одному из вариантов выше — выводим сообщение об ошибке
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.Run(async context =>
        {

           switch (context.Request.Path) 
            {
                case "/":
                    {
                        await context.Response.WriteAsync("Hello, Anonymous");
                        break;
                    }
                case "/date":
                    {
                        await context.Response.WriteAsync($"Date: {DateTime.Now.ToShortDateString()}");
                        break;
                    }
                case "/time":
                    {
                        await context.Response.WriteAsync($"Time: {DateTime.Now.ToShortTimeString()}");
                        break;
                    }
                    default: 
                    {
                        await context.Response.WriteAsync($"Error: Wrong path");
                        break;
                    }
            }
        });
        app.Run();
    }
}

Результат работы приложения

пустой путь

путь /date

путь /time

неизвестный путь

Как получить параметры запроса в ASP.NET Core?

Параметры запроса (см. на схеме компонент QUERY) совместно со значением пути позволяют идентифицировать ресурс. Для работы с параметрами запроса у HttpRequest имеются два свойства: QueryString и Query. Первое свойство возвращает не обработанную строку с параметрами запроса, а второе — параметры запроса в виде коллекции пар «ключ-значение».

Вначале посмотрим, какие значение могут возвращать эти свойства:

   public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.Run(async context =>
        {
            await context.Response.WriteAsync($"QueryString: {context.Request.QueryString} \r\n");
            foreach (var param in context.Request.Query)
            {
                await context.Response.WriteAsync($"{param.Key} - {param.Value} \r\n");
            }
        });
        app.Run();
    }
}

В результате мы можем получить, например, такой результат:

Теперь вернемся к нашему приложение и сделаем, например, возможность пользователю выбирать формат отображения даты, используя параметр format, который может принимать два значение — full и short, причем второе значение (short) — будет значением по умолчанию.

public static void Main(string[] args)
 {
     var builder = WebApplication.CreateBuilder(args);
     var app = builder.Build();

     app.Run(async context =>
     {
         //добавляем заголовок, чтобы корректно отображать кириллицу
         if (context.Response.HasStarted == false)
             context.Response.Headers.ContentType = "text/plain; charset=utf-8";
         //анализируем путь запроса
         switch (context.Request.Path) 
         {
             case "/":
                 {
                     await context.Response.WriteAsync("Hello, Anonymous");
                     break;
                 }
             case "/date":
                 {
                     //получаем значение параметра format
                     var format = context.Request.Query["format"].ToString();

                     if ((format == "")||(format=="short"))
                        await context.Response.WriteAsync($"Date: {DateTime.Now.ToShortDateString()}");
                     else
                         if (format=="full")
                             await context.Response.WriteAsync($"Date: {DateTime.Now.ToLongDateString()}");
                         else
                             await context.Response.WriteAsync($"Error: Wrong format");
                     break;
                 }
             case "/time":
                 {
                     await context.Response.WriteAsync($"Time: {DateTime.Now.ToShortTimeString()}");
                     break;
                 }
                 default: 
                 {
                     await context.Response.WriteAsync($"Error: Wrong path");
                     break;
                 }
         }
     });
     app.Run();
 }

здесь мы также добавили вариант обработки запроса в котором задается значение параметра format, отличное от full и short — в этом случае наше приложение вернет ошибку. Результат работы приложения:

запрос без параметра

с параметром со значением full

с параметром со значением short

с параметром со значением, отличным от допустимых

Таким образом, используя свойства Path и Query мы добавили в наше приложение простейшую систему маршрутизации. При этом, стоит отметить, что в ASP.NET Core имеются более удобные способы маршрутизации о которых мы ещё поговорим позднее.

Как получить значение порта в ASP.NET Core?

Наше приложение может «слушать» несколько портов и, как и в случае, с путём, в зависимости от того, по какому порту прошел запрос — менять логику работы. Чтобы получить значение порта, необходимо использовать свойство Host следующим образом:

var host = context.Request.Host.Host;
var port = context.Request.Host.Port;

Итого

Сегодня мы познакомились со свойством HttpRequest и научились получать заголовки запроса, а также использовать некоторые свойства HttpRequest для организации простейшей системы маршрутизации в нашем приложении ASP.NET Core.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии