Создание своего маршрута

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 16.11.2019

По умолчанию каждому маршруту сопоставляется некоторый шаблон, которому должна соответствовать строка запроса. Однако мы можем уйти от определения шаблонов и построить собственную логику применения маршрута к запросу через реализацию интерфейса Microsoft.AspNetCore.Routing.IRouter.

Этот интерфейс определяет два метода:

public interface IRouter 
{
	Task RouteAsync(RouteContext context);
	VirtualPathData GetVirtualPath(VirtualPathContext context);
}

Метод RouteAsync() предназначен для обработки входящих запросов. А метод GetVirtualPath() применяется для генерации ссылок в соответствии с данным маршрутом.

К примеру, добавим в проект класс AdminRoute:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System;
using System.Threading.Tasks;

namespace RoutingApp
{
    public class AdminRoute : IRouter
    {
        public VirtualPathData GetVirtualPath(VirtualPathContext context)
        {
            throw new NotImplementedException();
        }

        public async Task RouteAsync(RouteContext context)
        {
            string url = context.HttpContext.Request.Path.Value.TrimEnd('/');
            if (url.StartsWith("/Admin", StringComparison.OrdinalIgnoreCase))
            {
                context.Handler = async ctx =>
                {
                    ctx.Response.ContentType = "text/html;charset=utf-8";
                    await ctx.Response.WriteAsync("Привет admin!");
                };
            }
            await Task.CompletedTask;
        }
    }
}

Данный класс реализует метод RouteAsync(), который обрабатывает входящий запрос. В качестве параметра в RouteAsync передается объект RouteContext, через который мы можем получить доступ к данным запроса. В частности, здесь мы смотрим на первый сегмент строки запроса - если он начинается со строки "/Admin", то устанавливается обработчик маршрута, который отправляет в качестве ответа сообщение "Привет admin!".

Обработчик маршрута здесь также представляет делегат RequestDelegate, которому в качестве параметра из вызывающей среды передается объект RequestContext.

Метод GetVirtualPath() в данном случае нам не понабодится, поэтому он остается нереализованным.

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

public async Task RouteAsync(RouteContext context)
{
    string url = context.HttpContext.Request.Path.Value.TrimEnd('/');
    if (url.StartsWith("/Admin", StringComparison.OrdinalIgnoreCase))
    {
        await context.HttpContext.Response.WriteAsync("Привет admin!");
    }
}

Во втором случае запрос после обработки будет передаваться дальше по списку маршрутов и компонентов middleware, которые имеются в конвейере. А в первом случае запрос будет обрабатываться только тем делегатом, который установлен для свойства context.Handler.

Теперь применим этот маршрут в классе Startup:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Routing;

namespace RoutingApp
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRouting();
        }

        public void Configure(IApplicationBuilder app)
        {
            var routeBuilder = new RouteBuilder(app);

            routeBuilder.Routes.Add(new AdminRoute());

            routeBuilder.MapRoute("{controller}/{action}",
                async context => {
                    context.Response.ContentType = "text/html;charset=utf-8";
                    await context.Response.WriteAsync("двухсегментный запрос");
                });

            app.UseRouter(routeBuilder.Build());

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
}

С помощью вызова routeBuilder.Routes.Add(new AdminRoute()) маршрут добавляется на первое место в списке маршрутов. И в случае, если в запросе первый сегмент будет начинаться с "Admin", то он и будет соответствовать этому маршруту.

Создание маршрута в ASP.NET Core
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850