【问题标题】:Asp.net core middleware to run logic based on request urlAsp.net 核心中间件根据请求 url 运行逻辑
【发布时间】:2019-09-11 13:43:14
【问题描述】:

我有一个 .net 核心应用程序,它同时用作 api 网关和身份验证服务。身份验证控制器如下所示:

[AllowAnonymous]
    [HttpPost, Route("request")]
    public IActionResult RequestToken([FromBody] TokenRequest request)
    {

        string token = "";
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }


        if (_authService.IsAuthenticated(request, out token))
        {
            return Ok(token);
        }

        return BadRequest("Invalid Request");
    }

有没有办法创建一个可以区分请求 url 的中间件,这样我就可以在它像“/auth”和“OTHERS”这样的时候将它重定向到控制器。 “其他”应重定向到服务,该服务在 Configure 方法中运行以下内容:

app.Run(async (context) =>
            {
                using (var serviceScope = app.ApplicationServices.CreateScope())
                {
                    var routing = serviceScope.ServiceProvider.GetService<IRoutingService>();

                    var content = await routing.RouteRequest(context.Request);
                    await context.Response.WriteAsync(await content.Content.ReadAsStringAsync());
                    content.Dispose();

                    // Seed the database.
                }
            });

【问题讨论】:

    标签: asp.net-core microservices


    【解决方案1】:

    您可以为“其他”请求创建一个中间件,然后使用Map 方法映射到它:

    • 所以你有一个接口和一个实现,例如:
        public interface IRoutingService
        {
            Task<HttpResponseMessage> RouteRequest(HttpRequest request);
        }
    
        public sealed class RoutingService : IRoutingService
        {
            public Task<HttpResponseMessage> RouteRequest(HttpRequest request)
            {
                // your code    
            }
        }
    
    • 将其添加到服务中:
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddTransient<IRoutingService, RoutingService>();
            }
        }
    
    • IRoutingService 类型的构造函数中使用依赖注入定义中间件:
        public static class OthersExtensions
        {
            public static IApplicationBuilder UseOthers(this IApplicationBuilder builder)
            {
                return builder.UseMiddleware<OthersMiddleware>();
            }
        }
    
        public sealed class OthersMiddleware
        {
            private readonly IRoutingService routing;
    
            public OthersMiddleware(RequestDelegate _, IRoutingService routing) => this.routing = routing;
    
            public async Task Invoke(HttpContext context)
            {
                var content = await routing.RouteRequest(context.Request);
    
                await context.Response.WriteAsync(await content.Content.ReadAsStringAsync());
    
                content.Dispose();
            }
        }
    
    • 使用它:
        public class Startup
        {
            public void Configure(IApplicationBuilder app)
            {
                app.Map("/others", builder => builder.UseOthers());
            }
        }
    
    • 对于身份验证控制器,只需使用RouteAttribute 指定路由:
        [Route("auth")]
        public class AuthenticationController
        {
        }
    

    【讨论】:

    • 感谢您的回复。这似乎工作正常。但是我如何在去路由服务或身份验证控制器之间做出决定?我的意思是有没有办法知道传入的 URL?我想要实现的是: IF (AUTH) { GO TO CONTROLLER ACTION AUTH } ELSE { USE "others" MIDDLEWHERE }
    • @Flezcano 您不需要做出决定。只需指定身份验证控制器的路由即可。
    猜你喜欢
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 2021-12-08
    相关资源
    最近更新 更多