== 原文地址已不能訪問(wèn)捌显,停止本系列更新==
問(wèn)題
使用ASP.NET Core中間件創(chuàng)建Hello World
解決方案
從上一篇的空項(xiàng)目開(kāi)始,如下修正Startup.cs
中的Configure()
方法
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
// setup request pipeline using middleware
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World! (Run)");
});
}
一個(gè)不錯(cuò)的練習(xí)使用擴(kuò)展方法在IApplicationBuilder
上build pipeline:
// RunMiddlewareExtensions.cs
public static void RunHelloWorld(this IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World! (Run)");
});
}
// Startup.cs
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
// setup request pipeline using middleware
app.RunHelloWorld();
}
上一段代碼中我們使用IApplicationBuilder.Run()
配置中間件,另一種方法是用這個(gè)IApplicationBuilder.Run()
// UseMiddlewareExtensions.cs
public static IApplicationBuilder UseHelloWorld(
this IApplicationBuilder app)
{
return app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello World! (Use)\n");
await next();
});
}
// Startup.cs
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
// setup request pipeline using middleware
app.UseHelloWorld();
app.RunHelloWorld();
}
一個(gè)不錯(cuò)的練習(xí)如何使用中間件定義在單獨(dú)的類(lèi)中
public class HelloWorldMiddleware
{
private readonly RequestDelegate next;
public HelloWorldMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
await context.Response.WriteAsync("Hello World! (Use in Class)\n");
await this.next(context);
}
}
// UseMiddlewareExtensions.cs
public static IApplicationBuilder UseHelloWorldInClass(
this IApplicationBuilder app)
{
return app.UseMiddleware<HelloWorldMiddleware>();
}
// Startup.cs
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
// setup request pipeline using middleware
app.UseHelloWorld();
app.UseHelloWorldInClass();
app.RunHelloWorld();
}
討論
中間件是一個(gè)攔截HTTP請(qǐng)求和響應(yīng)消息的組件。我們創(chuàng)建這些組件連來(lái)構(gòu)建我們的應(yīng)用管道。
我們?cè)O(shè)置這個(gè)管道通過(guò)Configure()
方法挥吵,IApplicationBuilder
是參數(shù)重父,有下面三個(gè)方法:
-
Run():
添加一個(gè)中間件到管道花椭, 不繼續(xù)調(diào)用其他中間件 -
Use():
添加一個(gè)中間件,使用Lambda或者單獨(dú)的類(lèi) -
Map():
根據(jù)請(qǐng)求路徑添加中間件
Run
它用RequestDelegate
作為參數(shù)房午,當(dāng)調(diào)用的時(shí)候用HttpContext
作為參數(shù)矿辽, 返回void
無(wú)類(lèi)型,應(yīng)為這個(gè)是短的請(qǐng)求管道郭厌。
Use
它用Func
作為參數(shù)袋倔, 也就是把HttpContext
和指針(Pointer)傳到下一個(gè)中間件, 返回Task折柠。 如果下個(gè)中間件沒(méi)有調(diào)用宾娜,那他就是一個(gè)短的請(qǐng)求管道,和Run
一樣扇售。
UseMiddleware
當(dāng)我們?cè)O(shè)置一個(gè)中間件的類(lèi)時(shí)前塔,我們要用UseMiddleware
去包裝,提供我們的類(lèi)和泛型參數(shù)承冰。
獨(dú)立的中間件類(lèi)有兩個(gè)關(guān)鍵內(nèi)容:
- 構(gòu)成方法接受
RequestDelegate
华弓。 這個(gè)會(huì)調(diào)用請(qǐng)求到下一個(gè)中間件 - 它用
Invoke
接受參數(shù)HttpContext
返回Task
。 框架會(huì)根據(jù)需要調(diào)用中間件困乒。
注:用獨(dú)立的類(lèi)實(shí)現(xiàn)中間件并且用UseMdilleware
是最佳實(shí)踐
擴(kuò)展方法
知道擴(kuò)展方法的區(qū)別寂屏,RunXXX不支持返回值,然后UseXXX支持娜搂。這個(gè)是應(yīng)為Run()
是短路徑請(qǐng)求管道迁霎,而Use()
是以連的的形式連接其他中間件。
順序
中間件調(diào)用順序如他們?cè)?code>Configure()方法里百宇,按添加他們到管道的順序考廉。在響應(yīng)方面,返回給客戶(hù)端也是傳遞一樣的中間件管道恳谎。
Source Code
GitHub: