中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

宿遷做網(wǎng)站短視頻入口seo

宿遷做網(wǎng)站,短視頻入口seo,青海省教育廳門戶網(wǎng)站學(xué)籍查詢,注冊(cè)安全工程師白考了過(guò)濾器是 ASP.NET Core 中的特殊組件,允許我們?cè)谡?qǐng)求管道的特定階段控制請(qǐng)求的執(zhí)行。這些過(guò)濾器在中間件執(zhí)行后以及 MVC 中間件匹配路由并調(diào)用特定操作時(shí)發(fā)揮作用。 簡(jiǎn)而言之,過(guò)濾器提供了一種在操作級(jí)別自定義應(yīng)用程序行為的方法。它們就像檢查點(diǎn)&#…

????????過(guò)濾器是 ASP.NET Core 中的特殊組件,允許我們?cè)谡?qǐng)求管道的特定階段控制請(qǐng)求的執(zhí)行。這些過(guò)濾器在中間件執(zhí)行后以及 MVC 中間件匹配路由并調(diào)用特定操作時(shí)發(fā)揮作用。

????????簡(jiǎn)而言之,過(guò)濾器提供了一種在操作級(jí)別自定義應(yīng)用程序行為的方法。它們就像檢查點(diǎn),允許我們執(zhí)行特定任務(wù),例如異常處理、緩存或添加自定義響應(yīng)標(biāo)頭。

????????當(dāng)請(qǐng)求到達(dá)某個(gè)操作時(shí),過(guò)濾器可以收集有關(guān)已選擇哪個(gè)操作以及關(guān)聯(lián)的路由數(shù)據(jù)的信息。此信息可用于做出決策并執(zhí)行特定于該特定操作或控制器的操作。

????????通過(guò)使用過(guò)濾器,我們?cè)谔幚碚?qǐng)求時(shí)擁有更多的控制權(quán)和靈活性。我們可以根據(jù)我們的要求實(shí)現(xiàn)自定義邏輯并將特定行為應(yīng)用于不同的操作或控制器。這有助于在 ASP.NET Core 應(yīng)用程序中實(shí)現(xiàn)更加定制和高效的請(qǐng)求處理流程。

過(guò)濾器的類型

????????ASP.NET Core 提供了一組預(yù)定義的過(guò)濾器類型,允許我們?cè)诓僮骰蚩刂破鞯纳舷挛闹锌刂普?qǐng)求的執(zhí)行。這些過(guò)濾器有不同的用途,可以根據(jù)我們的要求進(jìn)行定制。

以下是 ASP.NET Core 中預(yù)定義過(guò)濾器的主要類型:

  1. AuthorizationFilter:此過(guò)濾器在路由執(zhí)行開(kāi)始時(shí)執(zhí)行。它確定是否允許用戶訪問(wèn)該路由或執(zhí)行請(qǐng)求的操作。

  2. ResourceFilter:該過(guò)濾器在授權(quán)后運(yùn)行,可用于繞過(guò)剩余管道的執(zhí)行。如果預(yù)處理的響應(yīng)可用,我們想要發(fā)送緩存的響應(yīng),從而跳過(guò)管道的其余部分,那么它非常有用。

  3. ActionFilter:動(dòng)作過(guò)濾器在動(dòng)作執(zhí)行之前和之后運(yùn)行。它提供了一種用自定義邏輯包圍操作或在執(zhí)行操作之前和之后執(zhí)行其他任務(wù)的方法。

  4. ResultFilter:此過(guò)濾器在操作生成結(jié)果之前和之后執(zhí)行。它允許我們用附加行為包圍結(jié)果執(zhí)行或根據(jù)結(jié)果執(zhí)行某些操作。

  5. ExceptionFilter:每當(dāng)操作或控制器中拋出未捕獲的異常時(shí),異常過(guò)濾器就會(huì)運(yùn)行。它提供了一種處理異常并設(shè)計(jì)特定于操作或控制器的自定義錯(cuò)誤響應(yīng)的方法。

  6. ServiceFilter:此過(guò)濾器運(yùn)行另一個(gè)過(guò)濾器,其類型在其自身內(nèi)傳遞。當(dāng)傳遞的過(guò)濾器類型注冊(cè)為服務(wù)時(shí)使用它。它解決通過(guò)依賴項(xiàng)注入 (DI) 傳遞給過(guò)濾器類型的任何依賴項(xiàng)。

  7. TypeFilter:與服務(wù)過(guò)濾器類似,類型過(guò)濾器也運(yùn)行未注冊(cè)為服務(wù)的過(guò)濾器類型。它允許我們應(yīng)用自定義過(guò)濾器而無(wú)需注冊(cè)。

????????這些預(yù)定義的過(guò)濾器類型使我們能夠靈活地控制請(qǐng)求執(zhí)行過(guò)程,并在 ASP.NET Core 應(yīng)用程序的管道的不同階段添加特定行為。

過(guò)濾器范圍?

????????ASP.NET Core 中過(guò)濾器的范圍取決于它們附加到 MVC 管道的方式。這使我們能夠控制過(guò)濾器執(zhí)行的時(shí)間和地點(diǎn)。過(guò)濾器的主要范圍分為三個(gè):

  1. 特定于操作的范圍:過(guò)濾器可以應(yīng)用于控制器內(nèi)的特定操作方法。通過(guò)使用過(guò)濾器屬性修飾操作,過(guò)濾器將僅在選擇該特定操作來(lái)處理傳入請(qǐng)求時(shí)執(zhí)行。

  2. 特定于控制器的范圍:過(guò)濾器也可以應(yīng)用于整個(gè)控制器類。當(dāng)過(guò)濾器應(yīng)用于控制器級(jí)別時(shí),它將針對(duì)該控制器內(nèi)的所有操作執(zhí)行。

  3. 全局范圍:全局過(guò)濾器應(yīng)用于路由中間件匹配和拾取的每條路由。這些過(guò)濾器被注冊(cè)為全局過(guò)濾器,并且無(wú)論特定操作或控制器如何都會(huì)被執(zhí)行。但是,如果沒(méi)有為請(qǐng)求選擇端點(diǎn),則不會(huì)執(zhí)行任何過(guò)濾器。

????????要將過(guò)濾器注冊(cè)為全局過(guò)濾器,可以將其添加到 Startup 類中的 ConfigureServices() 方法內(nèi)的過(guò)濾器數(shù)組中。這是一個(gè)例子:

services.AddControllers(options => {
? ? options.Filters.Add(typeof(ConsoleGlobalActionFilter));
});

????????在此示例中,使用 Add(typeof(...)) 方法將 ConsoleGlobalActionFilter 注冊(cè)為全局篩選器。這確保過(guò)濾器將應(yīng)用于路由中間件匹配和處理的每個(gè)路由。

????????通過(guò)控制過(guò)濾器的范圍,我們可以精確地確定過(guò)濾器將在 ASP.NET Core 應(yīng)用程序中應(yīng)用的時(shí)間和位置,從而允許我們添加特定的行為并有效地控制請(qǐng)求執(zhí)行過(guò)程。

如何創(chuàng)建簡(jiǎn)單的過(guò)濾器

有兩種方法可以創(chuàng)建我們之前討論的類型的過(guò)濾器。我們以創(chuàng)建ActionFilter為例:

  1. 實(shí)現(xiàn)接口:要?jiǎng)?chuàng)建根據(jù)操作執(zhí)行進(jìn)行操作的自定義操作過(guò)濾器,我們可以創(chuàng)建一個(gè)實(shí)現(xiàn) IActionFilter 或 IAsyncActionFilter 接口的類。這些接口提供了我們可以重寫以添加自定義邏輯的方法。通過(guò)實(shí)現(xiàn)這些接口,我們可以完全控制操作過(guò)濾器的行為。

  2. 擴(kuò)展屬性類:或者,我們可以創(chuàng)建一個(gè)擴(kuò)展 ActionFilterAttribute 類的自定義操作過(guò)濾器類。ActionFilterAttribute 類已經(jīng)實(shí)現(xiàn)了 IActionFilter 和 IAsyncActionFilter 接口。通過(guò)擴(kuò)展此類,我們可以重寫我們感興趣的方法并添加自定義邏輯。這種方法提供了一種更方便的方法來(lái)創(chuàng)建操作過(guò)濾器,因?yàn)槲覀兛梢灾苯訑U(kuò)展基類并專注于實(shí)現(xiàn)必要的方法。

????????同樣,對(duì)于提到的其他類型的過(guò)濾器(如授權(quán)過(guò)濾器、資源過(guò)濾器、結(jié)果過(guò)濾器、異常過(guò)濾器),也有相應(yīng)的可以實(shí)現(xiàn)的接口或可以擴(kuò)展的屬性類。

以下是上述過(guò)濾器的接口和屬性類:

  • IAuthorizationFilter:可以通過(guò)AuthorizationFilterAttribute實(shí)現(xiàn)或擴(kuò)展。

  • IResourceFilter:可以通過(guò)ResourceFilterAttribute實(shí)現(xiàn)或擴(kuò)展。

  • IActionFilter:可以通過(guò)ActionFilterAttribute實(shí)現(xiàn)或擴(kuò)展。

  • IResultFilter:可以通過(guò)ResultFilterAttribute實(shí)現(xiàn)或擴(kuò)展。

  • IExceptionFilter:可以通過(guò)ExceptionFilterAttribute實(shí)現(xiàn)或擴(kuò)展。

????????其中一些過(guò)濾器附帶有實(shí)現(xiàn)相應(yīng)接口的屬性類,使我們能夠靈活地重寫適合我們需要的特定方法。以下是一些過(guò)濾器的屬性類:

  • ActionFilterAttribute:該屬性類實(shí)現(xiàn) IActionFilter 和 IAsyncActionFilter 接口。通過(guò)擴(kuò)展這個(gè)類,我們可以直接繼承這些接口的實(shí)現(xiàn)并重寫我們感興趣的方法。這使得我們可以根據(jù)我們的需求自定義動(dòng)作過(guò)濾器的行為。

  • ExceptionFilterAttribute:該屬性類實(shí)現(xiàn) IExceptionFilter 接口。通過(guò)擴(kuò)展此類并重寫其方法,我們可以處理和自定義對(duì)操作或控制器中發(fā)生的異常的處理。這使我們能夠控制異常的處理方式,并允許我們提供自定義錯(cuò)誤響應(yīng)。

  • ResultFilterAttribute:該屬性類實(shí)現(xiàn) IResultFilter 接口。通過(guò)擴(kuò)展此類并重寫其方法,我們可以在將操作生成的結(jié)果發(fā)送回客戶端之前對(duì)其進(jìn)行修改。這允許我們向結(jié)果添加額外的處理或轉(zhuǎn)換。

  • FormatFilterAttribute:此屬性類用于指定操作或控制器支持的響應(yīng)格式。它有助于內(nèi)容協(xié)商并根據(jù)客戶的偏好選擇適當(dāng)?shù)捻憫?yīng)格式。

  • ServiceFilterAttribute:此屬性類用于應(yīng)用注冊(cè)為服務(wù)的過(guò)濾器。它允許我們使用依賴項(xiàng)注入來(lái)解決過(guò)濾器所需的任何依賴項(xiàng)。當(dāng)過(guò)濾器需要額外的服務(wù)或依賴項(xiàng)才能正常運(yùn)行時(shí),這會(huì)很有幫助。

  • TypeFilterAttribute:該屬性類與ServiceFilterAttribute類似,但它允許我們應(yīng)用未注冊(cè)為服務(wù)的過(guò)濾器。我們可以直接指定過(guò)濾器類型及其依賴項(xiàng)。

    ????????例如,ActionFilterAttribute類已經(jīng)為我們實(shí)現(xiàn)了IActionFilter和IAsyncActionFilter接口,因此我們可以直接擴(kuò)展ActionFilterAttribute類并重寫我們感興趣的方法。

using System; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Mvc.Filters; 
using Newtonsoft.Json;  public class AddResponseHeaderFilter : ActionFilterAttribute 
{     // Async method which can surround the action execution// Invoked before and after the action executionpublic asyn coverride Task OnActionExecutionAsync(         ActionExecutingContext context, ActionExecutionDelegate next)     {         // Access the request         context.HttpContext.Response.Headers.Add(             "X-MyCustomHeader", Guid.NewGuid().ToString());                  var result = await next.Invoke();                  // Access the response         Console.WriteLine(JsonConvert.SerializeObject(result.Result));     } 
}  [Route("api/[controller]")] 
[ApiController] 
public class HomeController : ControllerBase 
{     [AddResponseHeaderFilter]     [Route("")]     [HttpGet]     public IActionResult Index()     {         return Ok(new { Message = "I'm Alive" });     } 
}

????????在此示例中,我們通過(guò)擴(kuò)展ActionFilterAttribute創(chuàng)建了自定義AddResponseHeaderFilter類。此過(guò)濾器在執(zhí)行操作之前和之后向 HTTP 響應(yīng)添加自定義響應(yīng)標(biāo)頭。它重寫OnActionExecutionAsync方法,該方法允許我們自定義操作執(zhí)行周圍的行為。

????????然后,我們使用 [ AddResponseHeaderFilter ] 屬性將AddResponseHeaderFilter過(guò)濾器應(yīng)用到HomeController類的Index操作。這可確保針對(duì)該特定操作執(zhí)行過(guò)濾器。

????????調(diào)用該操作時(shí),過(guò)濾器使用Response.Headers.Add方法將自定義標(biāo)頭添加到響應(yīng)中。然后它調(diào)用 next.Invoke() 方法來(lái)繼續(xù)執(zhí)行操作。執(zhí)行操作后,它會(huì)訪問(wèn)響應(yīng)結(jié)果并使用JsonConvert.SerializeObject 將其寫入控制臺(tái)。

????????通過(guò)利用ActionFilterAttribute并創(chuàng)建自定義過(guò)濾器類,我們可以擴(kuò)展和自定義 ASP.NET Core 請(qǐng)求管道的行為,以添加其他功能并根據(jù)我們的要求修改響應(yīng)。

動(dòng)作過(guò)濾器的實(shí)現(xiàn)
示例 1:實(shí)現(xiàn) IActionFilter 的同步操作過(guò)濾器?

using Microsoft.AspNetCore.Mvc.Filters;namespace ActionFilters.Filters
{public class ActionFilterExample : IActionFilter{public void OnActionExecuting(ActionExecutingContext context){// Code executed before the action method executes}public void OnActionExecuted(ActionExecutedContext context){// Code executed after the action method executes}}
}

????????在此示例中,我們創(chuàng)建一個(gè)名為 ActionFilterExample 的類,該類實(shí)現(xiàn) IActionFilter 接口。該接口要求我們實(shí)現(xiàn)兩個(gè)方法:OnActionExecuting 和 OnActionExecuted。OnActionExecuting 方法包含將在操作方法之前執(zhí)行的代碼,而 OnActionExecuted 方法包含將在操作方法之后執(zhí)行的代碼。?

示例 2:實(shí)現(xiàn) IAsyncActionFilter 的異步操作過(guò)濾器?

using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;namespace ActionFilters.Filters
{public class AsyncActionFilterExample : IAsyncActionFilter{public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){// Code executed before the action method executesvar result = await next();// Code executed after the action method executes}}
}

????????在此示例中,我們創(chuàng)建一個(gè)名為 AsyncActionFilterExample 的類,該類實(shí)現(xiàn) IAsyncActionFilter 接口。該接口要求我們實(shí)現(xiàn) OnActionExecutionAsync 方法,該方法是動(dòng)作過(guò)濾器的異步版本。該方法接收一個(gè) ActionExecutingContext 和一個(gè) ActionExecutionDelegate。ActionExecutionDelegate 代表管道中的下一個(gè)操作,我們可以等待它執(zhí)行操作方法。通過(guò)這樣做,我們可以在操作方法執(zhí)行之前和之后運(yùn)行代碼。

????????通過(guò)創(chuàng)建實(shí)現(xiàn) IActionFilter 或 IAsyncActionFilter 的類,我們可以定義要在 ASP.NET Core 中的操作方法之前和之后執(zhí)行的自定義邏輯。這些操作過(guò)濾器提供了一種向請(qǐng)求管道添加附加行為并根據(jù)需要修改請(qǐng)求或響應(yīng)的方法。

?操作過(guò)濾器的范圍
可以在不同范圍級(jí)別添加操作過(guò)濾器:全局、操作和控制器。

1. 全局范圍

要全局使用操作過(guò)濾器,您可以在ConfigureServices方法的AddControllers()方法中注冊(cè)它:

public void ConfigureServices(IServiceCollection services)
{services.AddControllers(config =>{config.Filters.Add(new GlobalFilterExample());});
}

在.NET 6及更高版本中,由于缺少 Startup 類,您可以使用 Program 類:?

builder.Services.AddControllers(config => 
{ config.Filters.Add( new GlobalFilterExample()); 
});

通過(guò)將過(guò)濾器添加到全局范圍,它將應(yīng)用于整個(gè)應(yīng)用程序中的所有操作方法。

2. 操作和控制器范圍

如果要在操作或控制器級(jí)別使用操作過(guò)濾器,則需要在ConfigureServices方法中將其注冊(cè)為IoC容器中的服務(wù):

services.AddScoped<ActionFilterExample>(); 
services.AddScoped<ControllerFilterExample>();

在 .NET 6 及更高版本中:?

builder.Services.AddScoped<ActionFilterExample>(); 
builder.Services.AddScoped<ControllerFilterExample>();

????????通過(guò)將操作過(guò)濾器注冊(cè)為服務(wù),您可以通過(guò)使用相應(yīng)的過(guò)濾器屬性裝飾它們,有選擇地將其應(yīng)用到特定的操作方法或控制器。

????????最后,要使用在操作或控制器級(jí)別注冊(cè)的過(guò)濾器,您需要使用ServiceFilter屬性將其應(yīng)用到相應(yīng)的控制器或操作方法之上
namespace AspNetCore.Controllers
{[ServiceFilter(typeof(ControllerFilterExample))][Route("api/[controller]")][ApiController]public class TestController : ControllerBase{[HttpGet][ServiceFilter(typeof(ActionFilterExample))]public IEnumerable<string> Get(){return new string[] { "example", "data" };}}
}

????????通過(guò)使用[ServiceFilter]屬性并指定過(guò)濾器類型,您可以將注冊(cè)的過(guò)濾器(ControllerFilterExample 和 ActionFilterExample)分別與控制器和操作方法關(guān)聯(lián)起來(lái)。

????????這允許將過(guò)濾器應(yīng)用于指定的范圍,控制執(zhí)行流程并在執(zhí)行操作方法之前和之后提供附加功能。
????????以這種方式使用ServiceFilter屬性可以幫助您利用依賴項(xiàng)注入的優(yōu)勢(shì),并將所需的過(guò)濾器應(yīng)用到 ASP.NET 應(yīng)用程序中的特定控制器和操作方法。

調(diào)用順序
我們的過(guò)濾器的執(zhí)行順序如下:

我們可以通過(guò)向ServiceFilter屬性添加一個(gè)名為Order 的附加屬性來(lái)更改多個(gè)過(guò)濾器的調(diào)用順序?

namespace AspNetCore.Controllers
{[ServiceFilter(typeof(ControllerFilterExample), Order=2)][Route("api/[controller]")][ApiController]public class TestController : ControllerBase{[HttpGet][ServiceFilter(typeof(ActionFilterExample), Order=1)]public IEnumerable<string> Get(){return new string[] { "example", "data" };}}
}

????????在本例中,ControllerFilterExample將在ActionFilterExample之前執(zhí)行,因?yàn)樗鼈兊捻樞蛑捣謩e為 2 和 1。通過(guò)為過(guò)濾器分配不同的順序值,您可以控制它們的執(zhí)行順序。

您還可以將多個(gè)過(guò)濾器應(yīng)用于同一操作方法并定義它們的執(zhí)行順序:
[HttpGet] 
[ServiceFilter(typeof(ActionFilterExample), Order=2)] 
[ServiceFilter(typeof(ActionFilterExample2), Order=1)] 
public IEnumerable<string> Get() 
{ return new string[] { "example", "data ” }; 
}

?????????在這種情況下,ActionFilterExample2將根據(jù)其順序值分別為 1 和 2,在ActionFilterExample之前執(zhí)行。

????????通過(guò)指定每個(gè)過(guò)濾器的順序,您可以對(duì)執(zhí)行順序進(jìn)行細(xì)粒度控制,并且可以應(yīng)用具有不同優(yōu)先級(jí)的多個(gè)過(guò)濾器以在 ASP.NET 應(yīng)用程序中實(shí)現(xiàn)所需的行為。

使用操作過(guò)濾器改進(jìn)代碼
????????為了使用操作過(guò)濾器改進(jìn)代碼,讓我們重點(diǎn)關(guān)注存儲(chǔ)庫(kù)中AppStart文件夾中起始項(xiàng)目的Controllers文件夾中的MoveController類。該控制器包含所有 CRUD 操作的實(shí)現(xiàn)。

盡管我們的操作已經(jīng)干凈且可讀,但由于全局異常處理,我們可以進(jìn)一步增強(qiáng)它們。

需要注意的一件重要事情是我們的Movie模型繼承自IEntity接口:

[Table("Movie")]
public class Movie: IEntity
{[Key]public Guid Id { get; set; }[Required(ErrorMessage = "Name is required")]public string Name { get; set; }[Required(ErrorMessage = "Genre is required")]public string Genre { get; set; }[Required(ErrorMessage = "Director is required")]public string Director { get; set; }
}

?????????現(xiàn)在,讓我們關(guān)注POSTPUT操作的驗(yàn)證代碼。通過(guò)將適當(dāng)?shù)牟僮鬟^(guò)濾器應(yīng)用于POSTPUT操作,我們可以消除這些操作中顯式驗(yàn)證代碼的需要,使它們更加簡(jiǎn)潔和可維護(hù)。

使用操作過(guò)濾器進(jìn)行驗(yàn)證
????????為了改進(jìn)POST和PUT操作中的驗(yàn)證代碼,我們可以使用操作過(guò)濾器。通過(guò)將驗(yàn)證邏輯提取到自定義操作過(guò)濾器中,我們可以使代碼更具可重用性并保持操作更清晰。

????????首先,我們?cè)诮鉀Q方案資源管理器中創(chuàng)建一個(gè)名為“ActionFilters”的新文件夾。在該文件夾中,創(chuàng)建一個(gè)名為ValidationFilterAttribute的新類:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Linq;namespace ActionFilters.ActionFilters
{public class ValidationFilterAttribute : IActionFilter{public void OnActionExecuting(ActionExecutingContext context){var param = context.ActionArguments.SingleOrDefault(p => p.Value is IEntity);if (param.Value == null){context.Result = new BadRequestObjectResult("Object is null");return;}if (!context.ModelState.IsValid){context.Result = new UnprocessableEntityObjectResult(context.ModelState);}}public void OnActionExecuted(ActionExecutedContext context){          }}
}

?????????在ValidationFilterAttribute類中,我們重寫OnActionExecuting方法來(lái)執(zhí)行驗(yàn)證邏輯。我們檢查操作參數(shù)是否為 IEntity 類型,如果為 null,則返回BadRequestObjectResult。此外,如果 ModelState 無(wú)效,我們將返回UnprocessableEntityObjectResult。

????????接下來(lái),讓我們?cè)贑onfigureServices方法中將此操作過(guò)濾器注冊(cè)為服務(wù):

public void ConfigureServices(IServiceCollection services)
{services.AddDbContext<MovieContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("sqlConString")));services.AddScoped<ValidationFilterAttribute>();services.AddControllers();
}

對(duì)于.NET 6,我們需要在 Program 類中使用構(gòu)建器變量:?

builder.Services.AddDbContext<MovieContext>(options => options.UseSqlServer(Configuration.GetConnectionString( "sqlConString" ))); builder.Services.AddScoped<ValidationFilterAttribute>(); builder.Services.AddControllers();

最后,從 POST 和 PUT 操作中刪除驗(yàn)證代碼,并將ValidationFilterAttribute作為服務(wù)應(yīng)用:

[HttpPost]
[ServiceFilter(typeof(ValidationFilterAttribute))]
public IActionResult Post([FromBody] Movie movie)
{_context.Movies.Add(movie);_context.SaveChanges();return CreatedAtRoute("MovieById", new { id = movie.Id }, movie);
}[HttpPut("{id}")]
[ServiceFilter(typeof(ValidationFilterAttribute))]
public IActionResult Put(Guid id, [FromBody] Movie movie)
{var dbMovie = _context.Movies.SingleOrDefault(x => x.Id.Equals(id));if (dbMovie == null){return NotFound();}dbMovie.Map(movie);_context.Movies.Update(dbMovie);_context.SaveChanges();return NoContent();
}

????????通過(guò)將 ValidationFilterAttribute 應(yīng)用為服務(wù)過(guò)濾器,我們無(wú)需在操作中使用驗(yàn)證代碼。代碼現(xiàn)在更干凈、更具可讀性。此外,只要我們的模型類繼承自 IEntity 接口,此驗(yàn)證邏輯就可以重用。

????????為了確保操作過(guò)濾器的驗(yàn)證優(yōu)先于 [ApiController] 屬性的默認(rèn)驗(yàn)證行為,我們需要禁止默認(rèn)驗(yàn)證。在 Startup 類(或 .NET 6 的 Program 類)中,添加以下配置:
services.Configure<ApiBehaviorOptions>(options => 
{ options.SuppressModelStateInvalidFilter = true ; 
});

?????????此配置可確保返回操作過(guò)濾器的驗(yàn)證結(jié)果(例如,UnprocessableEntity),而不是返回驗(yàn)證錯(cuò)誤的默認(rèn)BadRequest結(jié)果。

????????通過(guò)這些更改,我們的驗(yàn)證過(guò)濾器已準(zhǔn)備好進(jìn)行測(cè)試。

動(dòng)作過(guò)濾器中的依賴注入
????????為了消除通過(guò) ID 從數(shù)據(jù)庫(kù)中獲取電影并在 GetById、DELETE 和 PUT 操作中檢查其是否存在的代碼重復(fù),我們可以創(chuàng)建一個(gè)新的操作過(guò)濾器來(lái)執(zhí)行此任務(wù)。我們還將使用依賴注入將 MovieContext 注入到動(dòng)作過(guò)濾器中。

讓我們?cè)?ActionFilters 文件夾中創(chuàng)建一個(gè)名為 ValidateEntityExistsAttribute<T> 的新操作過(guò)濾器類:

using System; 
using System.Linq; 
using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Mvc.Filters;  namespace ActionFilters.ActionFilters 
{     public class ValidateEntityExistsAttribute<T> : IActionFilter where T : class, IEntity     {         private readonly MovieContext _context;          public ValidateEntityExistsAttribute(MovieContext context)         {             _context = context;         }          public void OnActionExecuting(ActionExecutingContext context)         {             Guid id = Guid.Empty;              if (context.ActionArguments.ContainsKey("id"))             {                 id = (Guid)context.ActionArguments["id"];             }             else             {                 context.Result = new BadRequestObjectResult("Bad id parameter");                 return;             }              var entity = _context.Set<T>().SingleOrDefault(x => x.Id.Equals(id));             if (entity == null)             {                 context.Result = new NotFoundResult();             }             else             {                 context.HttpContext.Items.Add("entity", entity);             }         }          public void OnActionExecuted(ActionExecutedContext context)         {         }     } 
} 

????????在ValidateEntityExistsAttribute<T>類中,我們使用依賴注入通過(guò)構(gòu)造函數(shù)注入MovieContext 。該類是通用的,以便它可以重用于我們項(xiàng)目中的任何模型。在OnActionExecuting方法中,我們從操作上下文中獲取 ID 參數(shù)并檢查該實(shí)體是否存在于數(shù)據(jù)庫(kù)中。如果找到實(shí)體,我們會(huì)將其存儲(chǔ)在HttpContext .Items 集合中,以便稍后在操作方法中使用。

????????接下來(lái),讓我們?cè)?strong>ConfigureServices方法中注冊(cè)操作過(guò)濾器:

?services.AddScoped<ValidateEntityExistsAttribute<Movie>>();

????????對(duì)于 .NET 6,我們?cè)?Program 類中使用構(gòu)建器變量:?

builder.Services.AddScoped<ValidateEntityExistsAttribute<Movie>>();

最后,修改我們的操作以將 ValidateEntityExistsAttribute 應(yīng)用為服務(wù)過(guò)濾器:

[HttpGet("{id}", Name = "MovieById")] [ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))] 
public IActionResult Get(Guid id) 
{     var dbMovie = HttpContext.Items["entity"] as Movie;      return Ok(dbMovie); 
}  [HttpPut("{id}")] 
[ServiceFilter(typeof(ValidationFilterAttribute))] 
[ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))] 
public IActionResult Put(Guid id, [FromBody]Movie movie) 
{     var dbMovie = HttpContext.Items["entity"] as Movie;      dbMovie.Map(movie);      _context.Movies.Update(dbMovie);     _context.SaveChanges();      return NoContent(); 
}  [HttpDelete("{id}")] 
[ServiceFilter(typeof(ValidateEntityExistsAttribute<Movie>))] 
public IActionResult Delete(Guid id) 
{     var dbMovie = HttpContext.Items["entity"] as Movie;      _context.Movies.Remove(dbMovie);     _context.SaveChanges();      return NoContent(); 
} 

????????通過(guò)應(yīng)用ValidateEntityExistsAttribute<Movie>作為服務(wù)過(guò)濾器,我們確保從數(shù)據(jù)庫(kù)中獲取電影實(shí)體并通過(guò)HttpContext.Items在操作方法中可用。這消除了在獲取實(shí)體并檢查其存在時(shí)重復(fù)代碼的需要。

????????通過(guò)這些更改,我們的操作更加清晰、更具可讀性,并且通過(guò) ID 獲取實(shí)體的代碼現(xiàn)在可以重用。

http://www.risenshineclean.com/news/52222.html

相關(guān)文章:

  • 如何做一份企業(yè)網(wǎng)站規(guī)劃網(wǎng)絡(luò)營(yíng)銷策劃書(shū)總結(jié)
  • 湖南建設(shè)工程信息網(wǎng)一體化平臺(tái)網(wǎng)站seo置頂
  • 單位門戶網(wǎng)站建設(shè)方案google海外版入口
  • 買虛機(jī)送網(wǎng)站建設(shè)上海網(wǎng)絡(luò)推廣平臺(tái)
  • 岳陽(yáng)網(wǎng)站建設(shè)哪里便宜百度人工在線客服
  • 學(xué)做衣服上什么網(wǎng)站軟文廣告發(fā)稿
  • 手機(jī)網(wǎng)站制作平臺(tái)有哪些微商軟文范例大全100
  • 北京城鄉(xiāng)和住房建設(shè)部網(wǎng)站百度推廣首次開(kāi)戶需要多少錢
  • 網(wǎng)頁(yè)制作與網(wǎng)站建設(shè)廣州排名優(yōu)化哪家專業(yè)
  • 手機(jī)做網(wǎng)站公關(guān)公司
  • 資深網(wǎng)站百度學(xué)術(shù)論文官網(wǎng)入口
  • 公司 網(wǎng)站建設(shè) 簡(jiǎn)介付費(fèi)推廣
  • 制作圖片庫(kù)蘭州seo技術(shù)優(yōu)化排名公司
  • 唐山網(wǎng)站怎么做seo搜索引擎外部?jī)?yōu)化有哪些渠道
  • 佛山做網(wǎng)站yunzhanfs企業(yè)網(wǎng)絡(luò)推廣平臺(tái)
  • 網(wǎng)站建設(shè)全包需要多少錢廣州seo代理計(jì)費(fèi)
  • 建設(shè)高端網(wǎng)站公司網(wǎng)絡(luò)銷售推廣是做什么的具體
  • wordpress國(guó)內(nèi)能用嗎武漢標(biāo)兵seo
  • 金川做網(wǎng)站公司吸引客流的25個(gè)技巧
  • 營(yíng)山網(wǎng)站建設(shè)seo扣費(fèi)系統(tǒng)源碼
  • 廣州市網(wǎng)絡(luò)seo推廣seo秘籍優(yōu)化課程
  • 物理機(jī)安裝虛擬機(jī)做網(wǎng)站想建立自己的網(wǎng)站
  • ui作品集 網(wǎng)站怎么做搜素引擎優(yōu)化
  • wordpress 前臺(tái)刪除評(píng)論安徽網(wǎng)絡(luò)推廣和優(yōu)化
  • 做網(wǎng)站的圖片是怎么做的騰訊企點(diǎn)是干嘛的
  • 單頁(yè)網(wǎng)站設(shè)計(jì)最近一個(gè)月的熱點(diǎn)事件
  • 廣州網(wǎng)站建設(shè)360元陜西seo優(yōu)化
  • 公司做網(wǎng)站費(fèi)用會(huì)計(jì)分錄谷歌是如何運(yùn)營(yíng)的
  • 本地做網(wǎng)站貴seo搜索引擎優(yōu)化推廣
  • 網(wǎng)站開(kāi)發(fā)的前端語(yǔ)言是哪些品牌營(yíng)銷戰(zhàn)略