簡體   English   中英

asp.net 核心路由特定中間件

[英]asp.net core route specific middleware

我正在使用 KOA 2.0 並開始測試 asp.net 核心。 但是找不到處理請求/網址特定中間件的方法

在 Koa 中說,使用路由器我可以實現以下目標:

.post("/api/v1/user", Middleware1, Middleware2, RequestValidationMiddleware, SpecificAction);
.get("/api/v1/user", Middleware1, Middleware2, RequestValidationMiddleware, SpecificAction1);
.post("/api/v1/role", Middleware1, Middleware4, RequestValidationMiddleware2, SpecificAction2);

如何用asp.net核心實現它?

嘗試了以下內容:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    //app.UseApiLog();
    app.Map("/api", ApiLogApps);
    app.Map("/exlog", ExceptionLogApps);

    //app.UseMvc(routes =>
    //{
    //    routes.MapRoute(
    //                    name: "default",
    //                    template: "apilog/{controller}/{action}");
    //    routes.MapRoute(
    //                    name: "default2",
    //                    template: "exlog/{controller=Home}/{action=Index}/{id:int}");
    //});
}

private static void ApiLogApps(IApplicationBuilder app)
{
    //app.Run(() => )
    app.UseApiLog();
    app.UseMvc();
}

在控制器中我有

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("test/get/{id}")]
    public string Get(int id)
    {
        return "value";
    }
}

但我在這里迷路了。

我想要的是,我想要在中間件中處理 DataValidation - 這迫使我擁有每個 url(幾乎)特定的中間件。

PS - 我知道,模型驗證可以在行動中完成,但我不想要那樣。

在此先感謝您的幫助 :)

要使用 Koa2 等中間件,您可以配置一系列中間件來構建路由:

    public IRouter BuildRouter(IApplicationBuilder applicationBuilder)
    {
        var builder = new RouteBuilder(applicationBuilder);

        // use middlewares to configure a route
        builder.MapMiddlewareGet("/api/v1/user", appBuilder => {
            // your Middleware1
            appBuilder.Use(Middleware1);
            appBuilder.Use(Middleware2);
            appBuilder.Use(RequestValidationMiddleware);
            appBuilder.Run(SpecificAction);
        });

        builder.MapMiddlewarePost("/api/v1/user", appBuilder => {
            // your Middleware1
            appBuilder.Use(Middleware1);
            appBuilder.Use(Middleware2);
            appBuilder.Use(RequestValidationMiddleware);
            appBuilder.Run(SpecificAction1);
        });
        // ....

        return builder.Build();
    }

然后通過UseRouter(router)使用 RouterMiddleware :

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...
    app.UseRouter(BuildRouter(app));
    // ...
    app.UseMvc();
}

截圖:

在此處輸入圖片說明

[更新]:

要與屬性路由集成,只需添加一個UseMvc()代替Run() ,如下所示:

    public IRouter BuildRouter(IApplicationBuilder applicationBuilder)
    {
        var builder = new RouteBuilder(applicationBuilder);

        // use middlewares to configure a route
        builder.MapMiddlewareGet("/api/v1/user", appBuilder => {
            appBuilder.Use(Middleware1);
            appBuilder.Use(Middleware2);
            appBuilder.Use(RequestValidationMiddleware);
            appBuilder.UseMvc();          // use a MVC here ...
        });

        builder.MapMiddlewarePost("/api/v1/user", appBuilder => {
            appBuilder.Use(Middleware1);
            appBuilder.Use(Middleware2);
            appBuilder.Use(RequestValidationMiddleware);
            appBuilder.UseMvc();
        });
        // ....

        return builder.Build();
    }

只是為了演示, Middleware1 是一個虛擬中間件,它添加了HttpContext.Items['mw-message1']

    private Func<RequestDelegate, RequestDelegate> Middleware1 = next=> {
        return async context =>
        {
            context.Items["mw-message1"] = "mw1";
            await next(context);
        };
    };

Controller 是一個普通的控制器,它將檢索HttpContext.Items["mw-messages1"]

[Route("api/v1/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
    public IActionResult Index()
    {
        var x = (string)HttpContext.Items["mw-message1"];
        return new JsonResult(new {
            MW1 = x,
            Hello= "Hello",
        });
    }
}

現在,當向/api/v1/user發出 Get 請求時,最終響應是:

{"mW1":"mw1","hello":"Hello"}

我在 .net core 3 webapi 中使用以下代碼。

在startup.cs配置方法中添加以下內容以添加特定路由的中間件

//中間件檢查請求頭中是否存在授權密鑰 //映射到所有路由

_ = app.UseHeaderKeyAuthorization();

//映射到所有路由

_ = app.MapWhen(context => context.Request.Path.StartsWithSegments("/api/v1.0"), appBuilder =>
{
    _ = appBuilder.UseHeaderKeyAuthorization();
});

創建中間件HeaderKeyAuthorizationMiddleware,示例如下

//HeaderKeyAuthorizationMiddleware
public class HeaderKeyAuthorizationMiddleware
    {
        private readonly RequestDelegate next;

        public HeaderKeyAuthorizationMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            var authHeader = httpContext.Request.Headers[ApiConstants.AuthHeaderName];
            //check authHeader logic
            if (!string.IsNullOrEmpty(authHeader))
            {
                await next.Invoke(httpContext);
                return;
            }

            //Reject request if there is no authorization header or if it is not valid
            httpContext.Response.StatusCode = 401;
            await httpContext.Response.WriteAsync("Unauthorized");
        }
    }

//Middleware extension to register middleware   
public static class HeaderKeyAuthorizationMiddlewareExtension
    {
        public static IApplicationBuilder UseHeaderKeyAuthorization(this IApplicationBuilder app)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware<HeaderKeyAuthorizationMiddleware>();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM