设为首页 加入收藏

TOP

ASP.NET Core 中间件基本用法(一)
2019-09-17 18:01:15 】 浏览:37
Tags:ASP.NET Core 中间件 基本 用法

ASP.NET Core 中间件

ASP.NET Core的处理流程是一个管道,而中间件是装配到管道中的用于处理请求和响应的组件。中间件按照装配的先后顺序执行,并决定是否进入下一个组件。中间件管道的处理流程如下图(图片来源于官网):

image

管道式的处理方式,更加方便我们对程序进行扩展。

使用中间件

ASP.NET Core中间件模型是我们能够快捷的开发自己的中间件,完成对应用的扩展,我们先从一个简单的例子了解一下中间件的开发。

Run

首先,我们创建一个ASP.NET Core 应用,在Startup.cs中有如下代码:

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

这段代码中,使用Run方法运行一个委托,这就是最简单的中间件,它拦截了所有请求,返回一段文本作为响应。Run委托终止了管道的运行,因此也叫作终端中间件

Use

我们再看另外一个例子:

app.Use(async (context, next) =>
{
    //Do something here
    
    //Invoke next middleware
    await next.Invoke();
    
    //Do something here
    
});

这段代码中,使用Use方法运行一个委托,我们可以在Next调用之前和之后分别执行自定义的代码,从而可以方便的进行日志记录等工作。这段代码中,使用next.Invoke()方法调用下一个中间件,从而将中间件管道连贯起来;如果不调用next.Invoke()方法,则会造成管道短路

Map和MapWhen

处理上面两种方式,ASP.NET Core 还可以使用Map创建基于路径匹配的分支、使用MapWhen创建基于条件的分支。代码如下:

private static void HandleMap(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Handle Map");
    });
}

private static void HandleBranch(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        var branchVer = context.Request.Query["branch"];
        await context.Response.WriteAsync($"Branch used = {branchVer}");
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Map("/map", HandleMap);
    
    app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
               HandleBranch);
    
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Hello World!");
    });
}

上面的代码演示了如何使用Map和MapWhen创建基于路径和条件的分支。另外,Map方法还支持层级的分支,我们参照下面的代码:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

需要注意,使用 Map 时,将从 HttpRequest.Path 中删除匹配的Path,并针对每个请求将该线段追加到 HttpRequest.PathBase。例如对于路径/level1/level2a,当在level1App中进行处理时,它的请求路径被截断为/level2a,当在level2AApp中进行处理时,它的路径就变成/了,而相应的PathBase会变为/level1/level2a

开发中间件

看到这里,我们已经知道中间件的基本用法,是时候写一个真正意义的中间件了。

基于约定的中间件开发

在 ASP.NET Core 官网上面提供了一个简单的例子,通过中间件来设置应用的区域信息,代码如下:

public void Configure(IApplicationBuilder app)
{
    app.Use((context, next) =>
    {
        var cultureQuery = context.Request.Query["culture"];
        if (!string.IsNullOrWhiteSpace(cultureQuery))
        {
            var culture = new CultureInfo(cultureQuery);

            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;
        }

        // Call the next delegate/middleware in the pipeline
        return next();
    });

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(
            $"Hello {CultureInfo.CurrentCulture.DisplayName}");
    });
}

通过这段代码,我们可以通过QueryString的方式设置应用的区域信息。但是这样的代码怎样复用呢?注意,中间件一定要是可复用、方便复用的。我们来改造这段代码:

public class RequestCultureMiddleware
{
    private readonly RequestDelegate _next;

    public RequestCultureMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        //......

        // Call the next delegate/middleware in the pipeline
        await _next(context);
    }
}

这里定义一个委托,用于执行具体的业务逻辑,然后在Configure中调用这个委托:

app.UseMiddleware<RequestCultureMiddleware>();

这样还是不太方便,

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c#验证Textbox输入的IP地址格式是.. 下一篇.NET Core 3.0之创建基于Consul的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目