日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

asp.net core 中间件详解及项目实战

發(fā)布時(shí)間:2023/12/4 asp.net 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 asp.net core 中间件详解及项目实战 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在上篇文章主要介紹了DotNetCore項(xiàng)目狀況,本篇文章是我們?cè)陂_(kāi)發(fā)自己的項(xiàng)目中實(shí)際使用的,比較貼合實(shí)際應(yīng)用,算是對(duì)中間件的一個(gè)深入使用了,不是簡(jiǎn)單的Hello World,如果你覺(jué)得本篇文章對(duì)你有用的話,不妨點(diǎn)個(gè)【推薦】。

目錄

  • 中間件(Middleware)的作用

  • 中間件的運(yùn)行方式

  • 中間件(Middleware)和過(guò)濾器(Filter)的區(qū)別

  • 什么情況我們需要中間件

  • 怎么樣自定義自己的中間件

中間件(Middleware)的作用

我們知道,任何的一個(gè)web框架都是把http請(qǐng)求封裝成一個(gè)管道,每一次的請(qǐng)求都是經(jīng)過(guò)管道的一系列操作,最終到達(dá)我們寫(xiě)的代碼中。那么中間件就是在應(yīng)用程序管道中的一個(gè)組件,用來(lái)攔截請(qǐng)求過(guò)程進(jìn)行一些其他處理和響應(yīng)。中間件可以有很多個(gè),每一個(gè)中間件都可以對(duì)管道中的請(qǐng)求進(jìn)行攔截,它可以決定是否將請(qǐng)求轉(zhuǎn)移給下一個(gè)中間件。

asp.net core 提供了IApplicationBuilder接口來(lái)讓把中間件注冊(cè)到asp.net的管道請(qǐng)求當(dāng)中去,中間件是一個(gè)典型的AOP應(yīng)用。 下面是一個(gè)微軟官方的一個(gè)中間件管道請(qǐng)求圖:

可以看到,每一個(gè)中間件都都可以在請(qǐng)求之前和之后進(jìn)行操作。請(qǐng)求處理完成之后傳遞給下一個(gè)請(qǐng)求。

中間件的運(yùn)行方式

默認(rèn)情況下,中間件的執(zhí)行順序根據(jù)Startup.cs文件中,在public void Configure(IApplicationBuilder app){} 方法中注冊(cè)的先后順序執(zhí)行。
大概有3種方式可以在管道中注冊(cè)"中間件"

  • app.Use(),IApplicationBuilder接口原生提供,注冊(cè)等都用它。

  • app.Run() ,是一個(gè)擴(kuò)展方法,它需要一個(gè)RequestDelegate委托,里面包含了Http的上下文信息,沒(méi)有next參數(shù),因?yàn)樗偸窃诠艿雷詈笠徊綀?zhí)行。

  • app.Map(),也是一個(gè)擴(kuò)展方法,類(lèi)似于MVC的路由,用途一般是一些特殊請(qǐng)求路徑的處理。如:www.example.com/token 等。

  • 上面的Run,Map內(nèi)部也是調(diào)用的Use,算是對(duì)IApplicationBuilder接口擴(kuò)充,如果你覺(jué)得名字都不夠準(zhǔn)確,那么下面這個(gè)擴(kuò)展方法就是正宗的注冊(cè)中間件的了,也是功能最強(qiáng)大的。
    app.UseMiddleware<>(),沒(méi)錯(cuò),就是這個(gè)了。 為什么說(shuō)功能強(qiáng)大呢?是因?yàn)樗坏峁┝俗?cè)中間件的功能,還提供了依賴注入(DI)的功能,以后大部分情況就用它了。

    中間件(Middleware)和過(guò)濾器(Filter)的區(qū)別

    熟悉MVC框架的同學(xué)應(yīng)該知道,MVC也提供了5大過(guò)濾器供我們用來(lái)處理請(qǐng)求前后需要執(zhí)行的代碼。分別是AuthenticationFilter,AuthorizationFilter,ActionFilter,ExceptionFilter,ResultFilter。

    根據(jù)描述,可以看出中間件和過(guò)濾器的功能類(lèi)似,那么他們有什么區(qū)別?為什么又要搞一個(gè)中間件呢?
    其實(shí),過(guò)濾器和中間件他們的關(guān)注點(diǎn)是不一樣的,也就是說(shuō)職責(zé)不一樣,干的事情就不一樣。

    舉個(gè)栗子,中間件像是埃辛諾斯戰(zhàn)刃,過(guò)濾器像是巨龍之怒,泰蕾茍薩的寄魂杖 ,你一個(gè)戰(zhàn)士拿著巨龍之怒,泰蕾茍薩的寄魂杖去戰(zhàn)場(chǎng)殺人,雖然都有傷害,但是你拿著法杖傷害低不說(shuō),還減屬性啊。

    同作為兩個(gè)AOP利器,過(guò)濾器更貼合業(yè)務(wù),它關(guān)注于應(yīng)用程序本身,比如你看ActionFilter 和 ResultFilter,它都直接和你的Action,ActionResult交互了,是不是離你很近的感覺(jué),那我有一些比如對(duì)我的輸出結(jié)果進(jìn)行格式化啦,對(duì)我的請(qǐng)求的ViewModel進(jìn)行數(shù)據(jù)驗(yàn)證啦,肯定就是用Filter無(wú)疑了。它是MVC的一部分,它可以攔截到你Action上下文的一些信息,而中間件是沒(méi)有這個(gè)能力的。

    什么情況我們需要中間件

    那么,何時(shí)使用中間件呢?我的理解是在我們的應(yīng)用程序當(dāng)中和業(yè)務(wù)關(guān)系不大的一些需要在管道中做的事情可以使用,比如身份驗(yàn)證,Session存儲(chǔ),日志記錄等。其實(shí)我們的 asp.net core項(xiàng)目中本身已經(jīng)包含了很多個(gè)中間件。

    舉例,我們?cè)谛陆ㄒ粋€(gè) asp.net core應(yīng)用程序的時(shí)候,默認(rèn)生成的模板當(dāng)中

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory){app.UseDeveloperExceptionPage();app.UseStaticFiles();loggerFactory.AddConsole();app.UseMvc(routes =>{routes.MapRoute(name: "default", ? ? ? ? ? ?template: "{controller=Home}/{action=Index}/{id?}");}); }

    懶得去下載源碼了,我們使用Reflector去查看源碼:

    //擴(kuò)展方法`app.UseDeveloperExceptionPage();`public static class DeveloperExceptionPageExtensions{ ? ?// Methodspublic static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app) ? ?{ ? ? ? ?if (app == null){ ? ? ? ? ? ?throw new ArgumentNullException("app");} ? ? ? ?return UseMiddlewareExtensions.UseMiddleware<DeveloperExceptionPageMiddleware>(app, Array.Empty<object>());} } //擴(kuò)展方法`app.UseStaticFiles();`public static class StaticFileExtensions{ ? // Methodspublic static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app) ? ?{ ? ? ? ?if (app == null){ ? ? ? ? ? ?throw new ArgumentNullException("app");} ? ? ? ?return UseMiddlewareExtensions.UseMiddleware<StaticFileMiddleware>(app, Array.Empty<object>());} }

    可以看到 app.UseDeveloperExceptionPage(),app.UseStaticFiles()等等都是通過(guò)中間件實(shí)現(xiàn)的。

    怎么樣自定義自己的中間件

    背景:我們項(xiàng)目使用到中間件的情景是,需要和其他部門(mén)進(jìn)行用戶(User)信息的共享。 以平臺(tái)和子系統(tǒng)舉例,我們正在開(kāi)發(fā)一個(gè)子系統(tǒng),其中用戶信息,登錄,注冊(cè)等功能是放在平臺(tái)上的,這是一個(gè)跨多語(yǔ)言的系統(tǒng),平臺(tái)是Java語(yǔ)言開(kāi)發(fā),用戶在訪問(wèn)子系統(tǒng)的一些頁(yè)面的時(shí)候需要驗(yàn)證是否登錄,另外一些頁(yè)面是不需要驗(yàn)證是否登錄的,所以需要一個(gè)身份驗(yàn)證系統(tǒng)來(lái)代替Identity的功能。

    幸運(yùn)的是微軟已經(jīng)給我們提供了一套身份驗(yàn)證的中間件,在Microsoft.AspNetCore.Authentication命名空間下,我們只需要拓展,添加自己的功能就行了 。具體怎么做呢?直接看代碼吧。

    根據(jù)約定俗成,中間件類(lèi)需要有一個(gè)Invoke方法,簽名是public async Task Invoke(HttpContext context){},下面是一個(gè)中間件的示例類(lèi):

    public class RequestLoggerMiddleware{ ? ?private readonly RequestDelegate _next; ? ?private readonly ILogger _logger; ? ?public RequestLoggerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) ? ?{_next = next;_logger = loggerFactory.CreateLogger<RequestLoggerMiddleware>();} ? ?public async Task Invoke(HttpContext context) ? ?{_logger.LogInformation("Handling request: " + context.Request.Path); ? ? ? ?await _next.Invoke(context);_logger.LogInformation("Finished handling request.");} }

    了解了上面的約定之后,我們就開(kāi)始定義我們自己的中間件Class。

    我們需要一個(gè)流程圖來(lái)理清邏輯思路,以便于寫(xiě)代碼的時(shí)候思路更加的清晰。

    平臺(tái)有一個(gè)要求就是,用戶在我們子系統(tǒng)退出之后,要調(diào)用平臺(tái)的一個(gè)接口通知他們,他們要做一些后續(xù)的業(yè)務(wù)。

    OK,開(kāi)始擼碼。

    • 首先創(chuàng)建一個(gè)PlatformAuthoricationMiddleware,它繼承于Microsoft.AspNetCore.Authentication下的類(lèi)AuthenticationMiddleware,由于AuthenticationMiddleware已經(jīng)實(shí)現(xiàn)了Invoke功能,所以我們只需要重寫(xiě)(override)它里面的一些方法就可以了。等等,我們好像還需要一些配置,比如流程圖中的ReturnUrl,平臺(tái)的Cookie的Key值,平臺(tái)驗(yàn)證用戶合法性的接口地址等參數(shù)。

    • 建立一個(gè)Options類(lèi)進(jìn)行配置的設(shè)置,我們?nèi)∶譃?#xff1a;PlatformAuthenticationOptions,繼承AuthenticationOptions,并且實(shí)現(xiàn)掉IOptions<T>接口,這樣子就能在Startup中直接配置了。

    • 我們只需要重寫(xiě)AuthenticationMiddleware中的CreateHandler方法就行了,在Handler中可以實(shí)現(xiàn)掉我們中間件的功能。

    • 然后創(chuàng)建一個(gè)處理的Handler類(lèi),取名為PlatformAuthenticationHandler,繼承于AuthenticationHandler<TOptions>用來(lái)處理請(qǐng)求中的調(diào)用。

    至此,我們的核心需要的類(lèi)已經(jīng)建立完了,剩下的就是填充代碼。

  • 在PlatformAuthenticationHandler中重寫(xiě)HandleAuthenticateAsync()方法 , 進(jìn)行主流程的控制。

  • 在PlatformAuthenticationHandler中重寫(xiě)FinishResponseAsync()方法,進(jìn)行Session的存儲(chǔ)操作。

  • 在PlatformAuthenticationHandler中重寫(xiě)HandleSignOutAsync()方法,進(jìn)行登出的控制,因?yàn)橛脩舻浅鲋笪覀円ㄖ脚_(tái)做一些其他操作。

  • 在PlatformAuthenticationHandler中重寫(xiě)HandleUnauthorizedAsync()方法,進(jìn)行未認(rèn)證操作。

  • 最后,我們需要一個(gè)擴(kuò)展類(lèi)來(lái)把我們的中間件以擴(kuò)展方法注冊(cè)到管道當(dāng)中去 。

    public static class MiddlewareExtensions{ ? ?public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app) { ? ? ? ?if (app == null) { ? ? ? ? ? ?throw new ArgumentNullException(nameof(app));} ? ? ? ?return app.UseMiddleware<PlatformAuthenticationMiddleware>();} ? ?public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app, CookieAuthenticationOptions options) { ? ? ? ?if (app == null) { ? ? ? ? ? ?throw new ArgumentNullException(nameof(app));} ? ? ? ?if (options == null) { ? ? ? ? ? ?throw new ArgumentNullException(nameof(options));} ? ? ? ?return app.UseMiddleware<PlatformAuthenticationMiddleware>(Options.Create(options));} }

    在Startup中就是app.UsePlatformAuthentication()

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {loggerFactory.AddConsole(Configuration.GetSection("Logging")); ? ?//注冊(cè)PlatformAuthentication中間件app.UsePlatformAuthentication(new PlatformAuthenticationOptions() {UserSessionStore = new UserSessionStore(),});app.UseMvc(); }

    現(xiàn)在,我們的中間件核心業(yè)務(wù)流程的實(shí)現(xiàn)已經(jīng)出來(lái)了,我就不大篇幅的粘貼代碼了,會(huì)影響閱讀,感興趣具體實(shí)現(xiàn)的朋友可以去下面的地址查看代碼,有具體流程的注釋。

    示例源碼:
    https://github.com/yuleyule66/PlatformAuthMiddleware

    相關(guān)文章:

    • ASP.NET Core 1.0 入門(mén)——了解一個(gè)空項(xiàng)目

    • ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)

    • .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0簡(jiǎn)介

    • 云服務(wù)器下ASP.NET Core 1.0環(huán)境搭建(包含mono與coreclr)

    • 使用VS Code開(kāi)發(fā)ASP.NET Core 應(yīng)用程序

    • dotnet run是如何啟動(dòng)asp.net core站點(diǎn)的

    • ASP.NET Core提供模塊化Middleware組件

    • “dotnet restore"和"dotnet run"都做了些什么?

    • 探秘 dotnet run 如何運(yùn)行 .NET Core 應(yīng)用程序

    • .NET Portability Analyzer 已開(kāi)源

    • ASP.NET Core的配置(1):讀取配置信息

    • ASP.NET Core的配置(2):配置模型詳解

    • .NET Core 1.0 RC2 歷險(xiǎn)之旅

    • 使用VS Code開(kāi)發(fā) 調(diào)試.NET Core 應(yīng)用程序

    • 讓我們Core在一起:ASP.NET Core & .NET Core

    • .NET Core VS Code 環(huán)境配置

    • 官方博客明確了 .NET Core RC2/RTM 時(shí)間表

    • .NET Core全新的配置管理[共9篇]

    • 利用記事本創(chuàng)建一個(gè)ASP.NET Core RC2 MVC應(yīng)用

    • 微軟.NET 正式劈腿成功,橫跨所有平臺(tái)

    • .NET Core 1.0 CentOS7 嘗試

    • 解讀發(fā)布:.NET Core RC2 and .NET Core SDK Preview 1

    • [.NET Core].NET Core R2安裝及示例教程

    • ASP.NET Core 開(kāi)發(fā)-中間件(Middleware)

    • 結(jié)合Jexus + Kestrel 部署 asp.net core 生產(chǎn)環(huán)境

    • 通過(guò)Jexus 部署 dotnetcore版本MusicStore 示例程序

    • ASP.NET Core 中文文檔 第一章 入門(mén)

    • 用 Visual Studio Code 在 macOS 上創(chuàng)建首個(gè) ASP.NET Core 應(yīng)用程序

    • 用 Visual Studio 和 ASP.NET Core MVC 創(chuàng)建首個(gè) Web API

    • 用 Visual Studio 發(fā)布一個(gè) Azure 云 Web 應(yīng)用程序

    • ASP.NET Core MVC 與 Visual Studio 入門(mén)

    • 第二章指南(4.2)添加 Controller

    • DotNet Core 介紹


    原文地址:http://www.cnblogs.com/savorboard/p/5586229.html


    .NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注

    總結(jié)

    以上是生活随笔為你收集整理的asp.net core 中间件详解及项目实战的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。