asp .net core 中介軟體

夢裡小探花發表於2020-08-29

前言

對中介軟體的一個概況,在《重新整理.net core 計1400篇》系列後面會深入。

正文

什麼是中介軟體呢?

其實中介軟體這個概念來源於分散式,當然這是一個狹隘的概念了,現在中介軟體概念就非常廣泛了。

官網給出了這樣一張圖,這張圖認為從請求到響應過程中間都是中介軟體,包括我們認為的路由。

看一段node程式碼:

var http = require("http");
http.createServer(function(req,res){
   res.writeHead(200,{"Content-type":"text/blain"});
   res.write("Hello NodeJs");
   res.end();
}).listen(8888);

沒有學過node 也是ok的,從字面意思就是建立了一個http服務,然後埠是80。
createServer 可以傳入一個方法,中間有兩個引數,一個引數是req,另一個引數就是res。
其實就是這麼回事,我們寫的就是這個這個方法裡面的程式碼,至於,你想拿到req的什麼引數,或者給res寫入什麼資訊,這些都是中介軟體的範疇。

那麼問題來了,問什麼叫做中介軟體呢?從語文的層面上理解,那就是分開的,一件一件的。

把這件要執行的這些封裝成一個一個模組,那麼這些模組,這些可以通過呼叫next執行下一個模組,同樣,如果不呼叫,那麼中介軟體模組就會中斷,因為有時候真的需要中斷,比如說許可權中介軟體,

檢查到許可權不符合直接返回讓其跳轉到許可權頁面,剩下的模組也用不到。

用 Use 將多個請求委託連結在一起。 next 參數列示管道中的下一個委託。 可通過不呼叫 next 引數使管道短路。
當委託不將請求傳遞給下一個委託時,它被稱為“讓請求管道短路”。 通常需要短路,因為這樣可以避免不必要的工作。

下圖為asp .net core 中預設的中介軟體順序,當然可以自己修改,但是這是一種推薦做法。

挺合理的一個東西,一開始就填入了異常處理機制。

然後是強制https 轉換->重定向->靜態資原始檔->路由->是否跨域->認證->授權->我們自己自定義需求的。

因為這個endpoint 是不建議我們修改的,當然我們可以修改原始碼中,畢竟開源了,but not must。

官網中同樣給了我們這個endpoint 做了什麼,其實就是官方自己封裝了一些中介軟體。

當然我們也可以進行對endpoint自我的調整,因為可能使用不同的模板引擎:

app.UseEndpoints(endpoints =>
{
	endpoints.MapRazorPages();
	endpoints.MapControllerRoute(
		name: "default",
		pattern: "{controller=Home}/{action=Index}/{id?}");
});

從上面得到一個推薦的中介軟體註冊來看,認證和授權在靜態檔案之後,那麼我們知道我們的資源時需要授權來保護的。

那麼如何保護靜態資源呢?這後面會有專門的一章實踐一下,看下是什麼原理。

好的,那麼看一下我們如何自定義中介軟體吧,也就是實踐一下下面這種圖。


Middleware1

public class Middleware1
{
	public readonly RequestDelegate _next;

	public Middleware1(RequestDelegate next)
	{
		_next = next;
	}
	public async Task Invoke(HttpContext context)
	{
		Console.WriteLine("Middleware1");
		await _next(context);
		await context.Response.WriteAsync("Middleware1");
	}
}
public class Middleware2
{
	public readonly RequestDelegate _next;

	public Middleware2(RequestDelegate next)
	{
		_next = next;
	}
	public async Task Invoke(HttpContext context)
	{
		Console.WriteLine("Middleware2");
		await _next(context);
		await context.Response.WriteAsync("Middleware2");
	}
}

Middleware3

public class Middleware3
{
	public readonly RequestDelegate _next;

	public Middleware3(RequestDelegate next)
	{
		_next = next;
	}
	public async Task Invoke(HttpContext context)
	{
		Console.WriteLine("Middleware3");
		await _next(context);
		await context.Response.WriteAsync("Middleware3");
	}
}

擴充套件方法:

public static class Middleware1MiddlewareExtensions
{
	public static IApplicationBuilder UserMiddleware1(this IApplicationBuilder builder)
	{
		return builder.UseMiddleware<Middleware1>();
	}

	public static IApplicationBuilder UserMiddleware2(this IApplicationBuilder builder)
	{
		return builder.UseMiddleware<Middleware2>();
	}

	public static IApplicationBuilder UserMiddleware3(this IApplicationBuilder builder)
	{
		return builder.UseMiddleware<Middleware3>();
	}
}

加入中介軟體佇列:

app.UserMiddleware1();
app.UserMiddleware2();
app.UserMiddleware3();

request 順序

response 順序

這其實就是一種職責鏈模式,每個中介軟體確定是否該需求是否要下一級處理,同樣會產生一個處理回撥。

相關文章