Метод Map() применяется для создания ветки конвейера, которая будет обрабатывать запрос по определенному пути. Этот метод реализован как метод расширения для типа IApplicationBuilder и имеет ряд перегруженных версий. Например:
public static IApplicationBuilder Map (this IApplicationBuilder app, string pathMatch, Action<IApplicationBuilder> configuration);
В качестве параметра pathMatch
метод принимает путь запроса, с которым будет сопоставляться ветка. А параметр configuration
представляет делегат, в который передается объект IApplicationBuilder и в котором будет создаваться ветка конвейера.
Рассмотрим простой пример:
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.Map("/time", appBuilder => { var time = DateTime.Now.ToShortTimeString(); // логгируем данные - выводим на консоль приложения appBuilder.Use(async(context, next) => { Console.WriteLine($"Time: {time}"); await next(); // вызываем следующий middleware }); appBuilder.Run(async context => await context.Response.WriteAsync($"Time: {time}")); }); app.Run(async (context) => await context.Response.WriteAsync("Hello METANIT.COM")); app.Run();
В данном случае метод app.Map()
создает ответвление конвейера, которое будет обрабатывать запросы по пути "/time":
appBuilder => { var time = DateTime.Now.ToShortTimeString(); // логгируем данные - выводим на консоль приложения appBuilder.Use(async (context, next) => { Console.WriteLine($"Time: {time}"); await next(); // вызываем следующий middleware }); appBuilder.Run(async context => await context.Response.WriteAsync($"Time: {time}")); }
Созданная ветка конвейера содержит два middleware, встраиваемые с помощью методов Use()
и Run()
. Вначале получаем текущее время и в
первом middleware логгируем это время на консоль. Во втором - терминальном компоненте middleware отправляем информацию о времени в ответ клиенту.
При других путях запросах, отличных от "/time", запрос будет обрабатываться основным потоком конвейера, который состоит в данном случае из одного компонента:
app.Run(async (context) => await context.Response.WriteAsync("Hello METANIT.COM"));
Подобным образом можно создавать ветки для разных путей:
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.Map("/index", appBuilder => { appBuilder.Run(async context => await context.Response.WriteAsync("Index Page")); }); app.Map("/about", appBuilder => { appBuilder.Run(async context => await context.Response.WriteAsync("About Page")); }); app.Run(async (context) => await context.Response.WriteAsync("Page Not Found")); app.Run();
При необходимости создание веток конвейера можно вынести в отдельные методы:
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.Map("/index", Index); app.Map("/about", About); app.Run(async(context) => await context.Response.WriteAsync("Page Not Found")); app.Run(); void Index(IApplicationBuilder appBuilder) { appBuilder.Run(async context => await context.Response.WriteAsync("Index")); } void About(IApplicationBuilder appBuilder) { appBuilder.Run(async context => await context.Response.WriteAsync("About")); }
Ветка конвейера, которая создается в методе Map(), может иметь вложенные ветки, которые обрабатывают подзапросы. Например:
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.Map("/home", appBuilder => { appBuilder.Map("/index", Index); // middleware для "/home/index" appBuilder.Map("/about", About); // middleware для "/home/about" // middleware для "/home" appBuilder.Run(async (context) => await context.Response.WriteAsync("Home Page")); }); app.Run(async(context) => await context.Response.WriteAsync("Page Not Found")); app.Run(); void Index(IApplicationBuilder appBuilder) { appBuilder.Run(async context => await context.Response.WriteAsync("Index Page")); } void About(IApplicationBuilder appBuilder) { appBuilder.Run(async context => await context.Response.WriteAsync("About Page")); }
Здесь ветка создается с помощью вызова
app.Map("/home", appBuilder =>
Эта ветка будет обрабатывать запросы по пути "/home".
Внутри этой ветки создаются две вложенные ветки, которые будут обрабатывать запросы по путям относительно пути основной ветки. То есть теперь метод About будет обрабатывать запрос по пути "/home/about", а не "/about".