[Программирование, .NET, ASP, C#] Разбираемся с middleware в ASP.NET Core (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В преддверии курса "C# ASP.NET Core разработчик" приглашаем вас записаться на открытый урок по теме "Логирование и трейсинг запросов в asp.net core".
А пока делимся с вами традиционным полезным переводом.
Этой статья раскрывает концепции Middleware в ASP.NET Core. К концу этой статьи вы получите четкое представление о следующих моментах:
- Что такое Middleware?
- Почему порядок расположения Middleware имеет значение?
- Методы Run, Use и Map.
- Как создать собственное Middleware?
- Как реализовать просмотр каталогов с помощью Middleware?
Что такое Middleware?Middleware (промежуточное или связующее программное обеспечение) — это фрагмент кода в конвейере приложения, используемый для обработки запросов и ответов.Например, у нас может быть middleware-компонент для аутентификации пользователя, middleware-компонент для обработки ошибок и еще один middleware-компонент для обслуживания статических файлов, таких как файлы JavaScript, CSS, разного рода изображения и т. д. Middleware может быть встроенным как часть платформы .NET Core, добавляемым через пакеты NuGet или же написанным самим пользователем. Middleware-компоненты настраиваются в методе Сonfigure класса запуска приложения (Startup). Метод Configure выстраивает конвейер обработки запросов в ASP.NET Core приложении. Он состоит из последовательности делегатов запросов, вызываемых один за другим. На рисунке ниже показано, как запрос обрабатывается middleware-компонентами.
Как правило, каждое middleware обрабатывает входящие запросы и передает выполнение следующему middleware для дальнейшей обработки.Но middleware-компонент также может решить не вызывать следующую часть middleware в конвейере. Это называется замыканием (short-circuiting) или завершением конвейера запросов. Замыкание зачастую желательно, поскольку оно позволяет избежать ненужной работы. Например, если это запрос статического файла, такого как файл CSS, JavaScript, изображение и т. д., middleware-компонент для статических файлов может обработать и обслужить этот запрос, а затем замкнуть остальную часть конвейера. Давайте создадим ASP.NET Core веб-приложение и рассмотрим конфигурацию middleware по умолчанию в методе Configure класса Startup.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
//This middleware is used reports app runtime errors in development environment.
app.UseDeveloperExceptionPage();
}
else
{
//This middleware is catches exceptions thrown in production environment.
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts(); //adds the Strict-Transport-Security header.
}
//This middleware is used to redirects HTTP requests to HTTPS.
app.UseHttpsRedirection();
//This middleware is used to returns static files and short-circuits further request processing.
app.UseStaticFiles();
//This middleware is used to route requests.
app.UseRouting();
//This middleware is used to authorizes a user to access secure resources.
app.UseAuthorization();
//This middleware is used to add Razor Pages endpoints to the request pipeline.
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Фреймворк ASP.NET Core предоставляет встроенные middleware-компоненты, которые мы можем легко использовать, добавляя в метод Configure. Ознакомьтесь с документацией Microsoft для получения более подробной информации.Упорядочение MiddlewareMiddleware-компоненты выполняются в том порядке, в котором они добавляются в конвейер, по этому следует проявлять осторожность и добавлять middleware в правильном порядке, иначе приложение может работать не так, как вы ожидаете. Порядок расположения middleware важен для безопасности, производительности и функциональности.Следующие middleware-компоненты предназначены для стандартных сценариев приложений и расположены в рекомендуемом порядке:
Первый middleware-компонент в конфигурации получил запрос, изменил его (при необходимости) и передал управление следующему middleware. Точно так же первый middleware-компонент выполняется последним при обработке ответа, если мы возвращаем обратно эхо. Вот почему делегаты обработки исключений должны вызываться на самых ранних этапах конвейера - чтобы они могли проверить результат и отобразить возможное исключение в удобном для браузера и клиента виде.Методы Run, Use и Mapapp.Run()Этот метод добавляет middleware-компонент в виде Run[Middleware], который выполнится в конце конвейера. Как правило, он действует как замыкающее middleware и добавляется в конце конвейера запросов, поскольку не может вызывать следующий middleware-компонент. app.Use() Этот метод используется для конфигурирования нескольких middleware. В отличие от app.Run(), мы можем включить в него параметр next, который вызывает следующий делегат запроса в конвейере. Мы также можем замкнуть (завершить) конвейер, не вызывая параметр next. Давайте рассмотрим следующий пример с app.Use() и app.Run() и проанализируем результат/ответ:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Before Invoke from 1st app.Use()\n");
await next();
await context.Response.WriteAsync("After Invoke from 1st app.Use()\n");
});
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Before Invoke from 2nd app.Use()\n");
await next();
await context.Response.WriteAsync("After Invoke from 2nd app.Use()\n");
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello from 1st app.Run()\n");
});
// the following will never be executed
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello from 2nd app.Run()\n");
});
}
Первый делегат app.Run() завершает конвейер. В этом примере будет запущен только первый делегат («Hello from 1st app.Run()»), а запрос никогда не достигнет второго метода Run.app.Map()Этот метод расширения используются как условное обозначение для ветвления конвейера. Map разветвляет конвейер запросов на основе пути запроса. Если путь запроса начинается с указанного пути, ветвь выполняется.Давайте рассмотрим следующий пример с app.Map() и проанализируем результат/ответ:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Map("/m1", HandleMapOne);
app.Map("/m2", appMap => {
appMap.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd app.Map()");
});
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello from app.Run()");
});
}
private static void HandleMapOne(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 1st app.Map()");
});
}
В следующей таблице показаны запросы и ответы от localhost с использованием приведенного выше кода.RequestResponsehttps://localhost:44362/Hello from app.Run()https://localhost:44362/m1Hello from 1st app.Map()https://localhost:44362/m1/xyzHello from 1st app.Map()https://localhost:44362/m2Hello from 2nd app.Map()https://localhost:44362/m500Hello from app.Run()Создание собственного MiddlewareMiddleware обычно инкапсулируется в класс и предоставляется с помощью метода расширения. Middleware может быть создано с помощью класса с методом InvokeAsync() и параметром типа RequestDelegate в конструкторе. Тип RequestDelegate требуется для выполнения следующего middleware в последовательности.Рассмотрим пример, в котором нам нужно создать собственное middleware для регистрации URL-адреса запроса в веб-приложении.
public class LogURLMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LogURLMiddleware> _logger;
public LogURLMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
_next = next;
_logger = loggerFactory?.CreateLogger<LogURLMiddleware>() ??
throw new ArgumentNullException(nameof(loggerFactory));
}
public async Task InvokeAsync(HttpContext context)
{
_logger.LogInformation($"Request URL: {Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request)}");
await this._next(context);
}
}
public static class LogURLMiddlewareExtensions
{
public static IApplicationBuilder UseLogUrl(this IApplicationBuilder app)
{
return app.UseMiddleware<LogURLMiddleware>();
}
}
В методе Configure:
app.UseLogUrl();
Реализация просмотра каталогов с помощью Middleware Просмотр каталогов позволяет пользователям вашего веб-приложения видеть собственно сам список каталогов и файлы. Просмотр каталогов по умолчанию отключен из соображений безопасности. Давайте рассмотрим пример, в котором мы хотим реализовать просмотр списка изображений в браузере из папки с изображениями в wwwroot. Middleware UseDirectoryBrowser может обрабатывать и обслуживать эти изображения для такого рода запросов, а затем замкнуть остальную часть конвейера.
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")),
RequestPath = "/images"
});
Резюме Middleware в ASP.NET Core контролирует, как наше приложение отвечает на HTTP-запросы. Таким образом, каждый middleware-компонент в ASP.NET Core:
- Имеет доступ как к входящим запросам, так и к отправляемым обратно ответам.
- Может просто передать запрос следующему middleware в конвейере.
- Может выполнять некоторую логику обработки и затем передавать этот запрос следующему middleware для дальнейшей обработки.
- При необходимости может завершить (замкнуть) конвейер запросов.
- Выполняется в том порядке, в котором он был добавлены в конвейер.
Надеюсь, вы что-нибудь для себя почерпнули из этой статьи! Удачи вам в обучении!
Узнать подробнее о курсе и записаться на открытый урок можно здесь.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Anupam Maiti
===========Похожие новости:
- [Занимательные задачки, Математика] Чествуем игривое волшебство Джона Хортона Конвея (перевод)
- [Программирование, Машинное обучение] Ранжирование признаков с помощью Recursive Feature Elimination в Scikit-Learn (перевод)
- [Программирование, Разработка под MacOS, Компьютерное железо, Софт] Новым Mac с Apple M1 пока не хватает нативного софта и сред разработки
- [Программирование, Учебный процесс в IT, Карьера в IT-индустрии, IT-компании] Вы безумны, остановитесь пока не поздно
- [Python, Программирование] Каверзные вопросы по Python
- [Программирование, Проектирование и рефакторинг] Не бойтесь кода
- [.NET, Интерфейсы, Разработка под MacOS, Разработка под Linux, Разработка под Windows] Эволюция Material Design для AvaloniaUI
- [Программирование, Машинное обучение, Искусственный интеллект, Голосовые интерфейсы] Open Source синтез речи SOVA
- [Программирование, Разработка под Android] DIP vs IoC vs DI в мире Android
- [Машинное обучение, Статистика в IT, Софт] Как правильно рассчитать ROI в RPA
Теги для поиска: #_programmirovanie (Программирование), #_.net, #_asp, #_c#, #_middleware, #_asp.net_core, #_c#, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_programmirovanie (
Программирование
), #_.net, #_asp, #_c#
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 09:09
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В преддверии курса "C# ASP.NET Core разработчик" приглашаем вас записаться на открытый урок по теме "Логирование и трейсинг запросов в asp.net core".
А пока делимся с вами традиционным полезным переводом. Этой статья раскрывает концепции Middleware в ASP.NET Core. К концу этой статьи вы получите четкое представление о следующих моментах:
Как правило, каждое middleware обрабатывает входящие запросы и передает выполнение следующему middleware для дальнейшей обработки.Но middleware-компонент также может решить не вызывать следующую часть middleware в конвейере. Это называется замыканием (short-circuiting) или завершением конвейера запросов. Замыкание зачастую желательно, поскольку оно позволяет избежать ненужной работы. Например, если это запрос статического файла, такого как файл CSS, JavaScript, изображение и т. д., middleware-компонент для статических файлов может обработать и обслужить этот запрос, а затем замкнуть остальную часть конвейера. Давайте создадим ASP.NET Core веб-приложение и рассмотрим конфигурацию middleware по умолчанию в методе Configure класса Startup. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ if (env.IsDevelopment()) { //This middleware is used reports app runtime errors in development environment. app.UseDeveloperExceptionPage(); } else { //This middleware is catches exceptions thrown in production environment. app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); //adds the Strict-Transport-Security header. } //This middleware is used to redirects HTTP requests to HTTPS. app.UseHttpsRedirection(); //This middleware is used to returns static files and short-circuits further request processing. app.UseStaticFiles(); //This middleware is used to route requests. app.UseRouting(); //This middleware is used to authorizes a user to access secure resources. app.UseAuthorization(); //This middleware is used to add Razor Pages endpoints to the request pipeline. app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); } Первый middleware-компонент в конфигурации получил запрос, изменил его (при необходимости) и передал управление следующему middleware. Точно так же первый middleware-компонент выполняется последним при обработке ответа, если мы возвращаем обратно эхо. Вот почему делегаты обработки исключений должны вызываться на самых ранних этапах конвейера - чтобы они могли проверить результат и отобразить возможное исключение в удобном для браузера и клиента виде.Методы Run, Use и Mapapp.Run()Этот метод добавляет middleware-компонент в виде Run[Middleware], который выполнится в конце конвейера. Как правило, он действует как замыкающее middleware и добавляется в конце конвейера запросов, поскольку не может вызывать следующий middleware-компонент. app.Use() Этот метод используется для конфигурирования нескольких middleware. В отличие от app.Run(), мы можем включить в него параметр next, который вызывает следующий делегат запроса в конвейере. Мы также можем замкнуть (завершить) конвейер, не вызывая параметр next. Давайте рассмотрим следующий пример с app.Use() и app.Run() и проанализируем результат/ответ: public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ app.Use(async (context, next) => { await context.Response.WriteAsync("Before Invoke from 1st app.Use()\n"); await next(); await context.Response.WriteAsync("After Invoke from 1st app.Use()\n"); }); app.Use(async (context, next) => { await context.Response.WriteAsync("Before Invoke from 2nd app.Use()\n"); await next(); await context.Response.WriteAsync("After Invoke from 2nd app.Use()\n"); }); app.Run(async (context) => { await context.Response.WriteAsync("Hello from 1st app.Run()\n"); }); // the following will never be executed app.Run(async (context) => { await context.Response.WriteAsync("Hello from 2nd app.Run()\n"); }); } Первый делегат app.Run() завершает конвейер. В этом примере будет запущен только первый делегат («Hello from 1st app.Run()»), а запрос никогда не достигнет второго метода Run.app.Map()Этот метод расширения используются как условное обозначение для ветвления конвейера. Map разветвляет конвейер запросов на основе пути запроса. Если путь запроса начинается с указанного пути, ветвь выполняется.Давайте рассмотрим следующий пример с app.Map() и проанализируем результат/ответ: public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ app.Map("/m1", HandleMapOne); app.Map("/m2", appMap => { appMap.Run(async context => { await context.Response.WriteAsync("Hello from 2nd app.Map()"); }); }); app.Run(async (context) => { await context.Response.WriteAsync("Hello from app.Run()"); }); } private static void HandleMapOne(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hello from 1st app.Map()"); }); } public class LogURLMiddleware
{ private readonly RequestDelegate _next; private readonly ILogger<LogURLMiddleware> _logger; public LogURLMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory?.CreateLogger<LogURLMiddleware>() ?? throw new ArgumentNullException(nameof(loggerFactory)); } public async Task InvokeAsync(HttpContext context) { _logger.LogInformation($"Request URL: {Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(context.Request)}"); await this._next(context); } } public static class LogURLMiddlewareExtensions
{ public static IApplicationBuilder UseLogUrl(this IApplicationBuilder app) { return app.UseMiddleware<LogURLMiddleware>(); } } app.UseLogUrl();
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{ FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "images")), RequestPath = "/images" }); Резюме Middleware в ASP.NET Core контролирует, как наше приложение отвечает на HTTP-запросы. Таким образом, каждый middleware-компонент в ASP.NET Core:
Узнать подробнее о курсе и записаться на открытый урок можно здесь.
=========== Источник: habr.com =========== =========== Автор оригинала: Anupam Maiti ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_programmirovanie ( Программирование ), #_.net, #_asp, #_c# |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 09:09
Часовой пояс: UTC + 5