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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core 替换 Action 实际执行方法

發布時間:2023/12/4 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 替换 Action 实际执行方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

RequestDelegate

上次,我們在《如何判斷當前請求的API類型》中查看endpoints.MapControllers()實現時,最終定位到ActionEndpointFactory.cs,其中有這樣一段代碼:

private?static?RequestDelegate?CreateRequestDelegate() {//?We?don't?want?to?close?over?the?Invoker?Factory?in?ActionEndpointFactory?as//?that?creates?cycles?in?DI.?Since?we're?creating?this?delegate?at?startup?time//?we?don't?want?to?create?all?of?the?things?we?use?at?runtime?until?the?action//?actually?matches.////?The?request?delegate?is?already?a?closure?here?because?we?close?over//?the?action?descriptor.IActionInvokerFactory??invokerFactory?=?null;return?(context)?=>{var?endpoint?=?context.GetEndpoint()!;var?dataTokens?=?endpoint.Metadata.GetMetadata<IDataTokensMetadata>();var?routeData?=?new?RouteData();routeData.PushState(router:?null,?context.Request.RouteValues,?new?RouteValueDictionary(dataTokens?.DataTokens));//?Don't?close?over?the?ActionDescriptor,?that's?not?valid?for?pages.var?action?=?endpoint.Metadata.GetMetadata<ActionDescriptor>()!;var?actionContext?=?new?ActionContext(context,?routeData,?action);if?(invokerFactory?==?null){invokerFactory?=?context.RequestServices.GetRequiredService<IActionInvokerFactory>();}var?invoker?=?invokerFactory.CreateInvoker(actionContext);return?invoker!.InvokeAsync();}; }

從代碼上理解,應該是執行請求時,會創建IActionInvokerFactory實例,由它創建 invoker 執行。

是不是這樣呢,我們驗證一下!

IActionInvokerFactory

新建CustomActionInvokerFactory.cs,繼承IActionInvokerFactory,實現代碼如下:

public?class?CustomActionInvokerFactory?:?IActionInvokerFactory {private?readonly?IActionInvokerProvider[]?_actionInvokerProviders;public?ActionInvokerFactory(IEnumerable<IActionInvokerProvider>?actionInvokerProviders){_actionInvokerProviders?=?actionInvokerProviders.OrderBy(item?=>?item.Order).ToArray();}public?IActionInvoker??CreateInvoker(ActionContext?actionContext){var?context?=?new?ActionInvokerProviderContext(actionContext);foreach?(var?provider?in?_actionInvokerProviders){provider.OnProvidersExecuting(context);}for?(var?i?=?_actionInvokerProviders.Length?-?1;?i?>=?0;?i--){_actionInvokerProviders[i].OnProvidersExecuted(context);}return?context.Result;} }

代碼 Copy 自 ASP.NET Core 內部實現類ActionInvokerFactory。

然后在 Startup.cs 注冊實現:

public?void?ConfigureServices(IServiceCollection?services) {services.AddSingleton<IActionInvokerFactory,?CustomActionInvokerFactory>();... }

打上斷點,執行API,發現確實如設想中一樣,請求時執行CreateInvoker方法:

在其中發現了一個很有意思的屬性MethodInfo,正是對應我們執行的 Action 方法。

突發奇想,如果我們替換MethodInfo屬性,是不是會執行其他方法呢?

Demo

創建 WeatherForecast2Controller,實現代碼如下:

[ApiController] [Route("[controller]")] public?class?WeatherForecast2Controller?:?ControllerBase {[HttpGet]public?string?Get2(){return?"My?IO";} }

可以看到這是和原方法完全不同的實現。

現在進行替換:

var?actionDescriptor?=?actionContext.ActionDescriptor?as?ControllerActionDescriptor; actionDescriptor.MethodInfo?=?typeof(WeatherForecast2Controller).GetMethod("Get2");

執行,出現錯誤提示:

查看ControllerActionInvokerCache.cs實現:

var?objectMethodExecutor?=?ObjectMethodExecutor.Create(actionDescriptor.MethodInfo,actionDescriptor.ControllerTypeInfo,parameterDefaultValues);

原來,還要替換actionDescriptor.ControllerTypeInfo:

var?actionDescriptor?=?actionContext.ActionDescriptor?as?ControllerActionDescriptor; actionDescriptor.MethodInfo?=?typeof(WeatherForecast2Controller).GetMethod("Get2"); actionDescriptor.ControllerTypeInfo?=?typeof(WeatherForecast2Controller).GetTypeInfo();

再次運行,執行成功!

結論

替換 Action 實際執行方法,最好的使用場景是定制化開發,比如客戶需求和產品實現完全不同,可以保證請求不變的情況下執行客戶定制化實現。

想了解更多內容,請關注我的個人公眾號”My IO“

總結

以上是生活随笔為你收集整理的ASP.NET Core 替换 Action 实际执行方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。