首页 > 解决方案 > 为什么在 ASP.NET Core 中首先使用 DynamicRouteValueTransformer 评估动态包罗万象的路由?

问题描述

我正在尝试设置一个动态路由包罗万象,以便将所有与硬编码路由不匹配的路由发送到 DynamicRouteValueTransformer,后者试图在数据库中查找动态路由。

我遇到的问题是,首先对所有请求进行评估,即使对于 .js 或 .css 等静态文件也是如此。我怎样才能解决这个问题?

启动/配置

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseWebOptimizer();
    app.UseHttpsRedirection();
    app.UseCookiePolicy();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        // Secure-route.
        endpoints.MapAreaControllerRoute(name: "secure-route", areaName: "Secure", pattern: "Secure/{controller=Dashboard}/{action=index}/{id?}");

        // Startpage
        endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}");

        endpoints.MapControllerRoute(name: "Orders", pattern: "{controller=Orders}/{action=Index}");

        // Razorpages for identity
        endpoints.MapRazorPages();

        // Catch-all for cms-routes
        endpoints.MapDynamicControllerRoute<CustomRouteTransformer>("{**slug}");
    });
}

DynamicRouteValueTransformer-代码:

public class CustomRouteTransformer : DynamicRouteValueTransformer
{
    private readonly IRouteProjectionService _routeService;

    public CustomRouteTransformer(IRouteProjectionService routeService)
    {
        _routeService = routeService;
    }

    public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
    {
        // Get contentpage based on URL
        var url = httpContext.Request.Path.ToString();
        var contentPage = _routeService.GetRoute(url).Result;

        values["controller"] = contentPage.Controller;
        values["action"] = contentPage.Action;
        values["viewName"] = contentPage.View;
        values["pageId"] = contentPage.Id;

        return new ValueTask<RouteValueDictionary>(values);
    }
}

路线投影服务:

public class RouteProjectionService : IRouteProjectionService
{
    private readonly IAsyncRepository<ContentPage> _contentPageRepository;
    private readonly IAsyncRepository<PageTemplate> _pageTemplateRepository;
    private readonly ILogger<RouteProjectionService> _logger;
    public RouteProjectionService(IAsyncRepository<ContentPage> contentPageRepository,
                                  IAsyncRepository<PageTemplate> pageTemplateRepository,
                                  ILogger<RouteProjectionService> logger)
    {
        _contentPageRepository = contentPageRepository;
        _pageTemplateRepository = pageTemplateRepository;
        _logger = logger;
    }
    public async Task<RouteProjection> GetRoute(string url)
    {
        try
        {
            var spec = new ContentPageAndRouteSpecificationByUrl(url);
            var contentPage = await _contentPageRepository.FirstOrDefaultAsync(spec);
            if (contentPage == null)
            {
                _logger.LogError("No contentpage found");
                return null;
            }
            
            var projection = new RouteProjection
            {
                Url = contentPage.Url,
                Name = contentPage.PageTemplate.Name,
                Id = contentPage.Id,
                Action = contentPage.PageTemplate.Action,
                Controller = contentPage.PageTemplate.Controller,
                View = contentPage.PageTemplate.View,
                ContentPageType = contentPage.PageTemplate.ContentPageType
            };

            return projection;
        }
        catch (Exception ex)
        {
            throw new Exception("error setting up routes", ex.InnerException);
        }
    }
}

标签: c#asp.net-coreasp.net-core-3.1

解决方案


推荐阅读