解读ASP.NET 5 & MVC6系列教程(6):Middleware详解

2019-05-22 14:44:59于海丽

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
 app.UseTimeRecorderMiddleware(); // 要放在前面,以便进行统计,如果放在Mvc后面的话,就统计不了时间了。

 // 等等
}

编译,重启,并访问页面,在页面的底部即可看到页面的运行时间提示内容。

常用Middleware功能的使用

app.UseErrorPage()
在IHostingEnvironment.EnvironmentName为Development的情况下,才显示错误信息,并且错误信息的显示种类,可以通过额外的ErrorPageOptions参数来设定,可以设置全部显示,也可以设置只显示Cookies、Environment、ExceptionDetails、Headers、Query、SourceCode SourceCodeLineCount中的一种或多种。

app.UseErrorHandler("/Home/Error")
捕获所有的程序异常错误,并将请求跳转至指定的页面,以达到友好提示的目的。

app.UseStaticFiles()
开启静态文件也能走该Pipeline管线处理流程的功能。

app.UseIdentity()
开启以cookie为基础的ASP.NET identity认证功能,以支持Pipeline请求处理。

直接使用委托定义Middleware的功能

由于Middleware是Func<RequestDelegate, RequestDelegate>委托类型的实例,所以我们也可以不必定义一个单独的类,在Startup类里,使用委托调用的方式就可以了,示例如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
 app.Use(new Func<RequestDelegate, RequestDelegate>(next => content => Invoke(next, content)));
 // 其它
}

// 注意Invoke方法的参数
private async Task Invoke(RequestDelegate next, HttpContext content)
{
 Console.WriteLine("初始化组件开始");
 await next.Invoke(content);
 Console.WriteLine("管道下步执行完毕");
}

做个简便的Middleware基类

虽然有约定方法,但有时候我们在开发的时候往往会犯迷糊,想不起来到底是什么样的约定,所以,在这里我们可以定义一个抽象基类,然后以后所有的Middleware在定义的时候都继承该抽象类并重载Invoke方法即可,从而可以避免约定忘记的问题。代码如下:

/// <summary>
/// 抽象基类
/// </summary>
public abstract class AbstractMiddleware
{
 protected RequestDelegate Next { get; set; }
 protected AbstractMiddleware(RequestDelegate next)
 {
  this.Next = next;
 }
 public abstract Task Invoke(HttpContext context);
}

/// <summary>
/// 示例Middleware
/// </summary>
public class DemoMiddleware : AbstractMiddleware
{
 public DemoMiddleware(RequestDelegate next) : base(next)
 {
 }
 public async override Task Invoke(HttpContext context)
 {
  Console.WriteLine("DemoMiddleware Start.");
  await Next.Invoke(context);
  Console.WriteLine("DemoMiddleware End.");
 }
}

使用方法和上面的一样。