HttpResponse在ASP.NET 5中都是重新定义的新类型。
Middleware的定义
既然每个middleare都是Func<RequestDelegate, RequestDelegate>的一个实例,那是不是Middleware的定义要满足一个规则?是继承于一个抽象基类还是借口?通过翻查相关的代码,我们看到,Middleware是基于约定的形式来定义的,具体约定规则如下:
构造函数的第一个参数必须是处理管线中的下一个处理函数,即RequestDelegate;必须有一个 Invoke 函数, 并接受上下文参数(即HttpContent), 然后返回 Task;
示例如下:
public class MiddlewareName
{
RequestDelegate _next;
public MiddlewareName(RequestDelegate next)
{
_next = next;// 接收传入的RequestDelegate实例
}
public async Task Invoke(HttpContext context)
{
// 处理代码,如处理context.Request中的内容
Console.WriteLine("Middleware开始处理");
await _next(context);
Console.WriteLine("Middleware结束处理");
// 处理代码,如处理context.Response中的内容
}
}
通过该模板代码可以看到,首先一个Middleware的构造函数要接收一个RequestDelegate的实例,先保存在一个私有变量里,然后通过调用Invoke方法(并接收HttpContent实例)并返回一个Task,并且在调用Invoke的方法中,要通过await _next(context);语句,链式到下一个Middleware上,我们的处理代码主要就是在链式语句的前后执行相关的代码。
举个例子,如果我们要想记录页面的执行时间,首先,我们先定义一个TimeRecorderMiddleware,代码如下:
public class TimeRecorderMiddleware
{
RequestDelegate _next;
public TimeRecorderMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var sw = new Stopwatch();
sw.Start();
await _next(context);
var newDiv = @"<div id=""process"">页面处理时间:{0} 毫秒</div></body>";
var text = string.Format(newDiv, sw.ElapsedMilliseconds);
await context.Response.WriteAsync(text);
}
}
Middleware的注册有很多种方式,如下是实例型注册代码:
app.Use(next => new TimeRecorderMiddleware(next).Invoke);
或者,你也可以使用UseMiddleware扩展方法进行注册,示例如下:
app.UseMiddleware<TimeRecorderMiddleware>(); //app.UseMiddleware(typeof(TimeRecorderMiddleware)); 两种方式都可以
当然,你也可以定义一个自己的扩展方法用于注册该Middleware,代码如下:
public static IApplicationBuilder UseTimeRecorderMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<TimeRecorderMiddleware>();
}
最后在Startup类的Configure方法内进行注册,代码如下:








