{"id":1855,"date":"2023-06-14T13:03:28","date_gmt":"2023-06-14T13:03:28","guid":{"rendered":"http:\/\/waqar-arshad.com\/?p=1855"},"modified":"2023-06-14T13:06:29","modified_gmt":"2023-06-14T13:06:29","slug":"asp-net-core-extended","status":"publish","type":"post","link":"http:\/\/waqar-arshad.com\/index.php\/2023\/06\/14\/asp-net-core-extended\/","title":{"rendered":"Asp.Net Core Extended"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1855\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">1    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1855\" data-trigger-type=\"dislike\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>\n<p><strong>Filters in ASP.NET Core<\/strong><\/p>\n\n\n\n<p><em>Filters<\/em>&nbsp;in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline.<\/p>\n\n\n\n<p>Built-in filters handle tasks such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Authorization, preventing access to resources a user isn&#8217;t authorized for.<\/li>\n\n\n\n<li>Response caching, short-circuiting the request pipeline to return a cached response.<\/li>\n<\/ul>\n\n\n\n<p>Custom filters can be created to handle cross-cutting concerns. Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Filters avoid duplicating code. For example, an error handling exception filter could consolidate error handling.<\/p>\n\n\n\n<p>This document applies to Razor Pages, API controllers, and controllers with views. Filters don&#8217;t work directly with&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/blazor\/components\/?view=aspnetcore-6.0\">Razor components<\/a>. A filter can only indirectly affect a component when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The component is embedded in a page or view.<\/li>\n\n\n\n<li>The page or controller and view uses the filter.<\/li>\n<\/ul>\n\n\n\n<p><strong>How filters work<\/strong><\/p>\n\n\n\n<p>Filters run within the\u00a0<em>ASP.NET Core action invocation pipeline<\/em>, sometimes referred to as the\u00a0<em>filter pipeline<\/em>. The filter pipeline runs after ASP.NET Core selects the action to execute:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"625\" height=\"896\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-29.png\" alt=\"\" class=\"wp-image-1856\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-29.png 625w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-29-209x300.png 209w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/figure>\n\n\n\n<p><strong>Filter types<\/strong><\/p>\n\n\n\n<p>Each filter type is executed at a different stage in the filter pipeline:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#authorization-filters\">Authorization filters<\/a>:<ul><li>Run first.<\/li><\/ul><ul><li>Determine whether the user is authorized for the request.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>Short-circuit the pipeline if the request is not authorized.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#resource-filters\">Resource filters<\/a>:<ul><li>Run after authorization.<\/li><\/ul><ul><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresourcefilter.onresourceexecuting\">OnResourceExecuting<\/a>&nbsp;runs code before the rest of the filter pipeline. For example,&nbsp;OnResourceExecuting&nbsp;runs code before model binding.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresourcefilter.onresourceexecuted\">OnResourceExecuted<\/a>&nbsp;runs code after the rest of the pipeline has completed.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#action-filters\">Action filters<\/a>:<ul><li>Run immediately before and after an action method is called.<\/li><\/ul><ul><li>Can change the arguments passed into an action.<\/li><\/ul><ul><li>Can change the result returned from the action.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>Are&nbsp;<strong>not<\/strong>&nbsp;supported in Razor Pages.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#exception-filters\">Exception filters<\/a>&nbsp;apply global policies to unhandled exceptions that occur before the response body has been written to.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#result-filters\">Result filters<\/a>:<ul><li>Run immediately before and after the execution of action results.<\/li><\/ul><ul><li>Run only when the action method executes successfully.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>Are useful for logic that must surround view or formatter execution.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>The following diagram shows how filter types interact in the filter pipeline:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"697\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-30.png\" alt=\"\" class=\"wp-image-1857\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-30.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-30-300x222.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-30-768x569.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Razor Pages also support&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/razor-pages\/filter?view=aspnetcore-6.0\">Razor Page filters<\/a>, which run before and after a Razor Page handler.<\/p>\n\n\n\n<p><strong>Implementation<\/strong><\/p>\n\n\n\n<p>Filters support both synchronous and asynchronous implementations through different interface definitions.<\/p>\n\n\n\n<p>Synchronous filters run before and after their pipeline stage. For example,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iactionfilter.onactionexecuting\">OnActionExecuting<\/a>&nbsp;is called before the action method is called.&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iactionfilter.onactionexecuted\">OnActionExecuted<\/a>&nbsp;is called after the action method returns:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleActionFilter : IActionFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnActionExecuting(ActionExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something before the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnActionExecuted(ActionExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something after the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Asynchronous filters define an&nbsp;On-Stage-ExecutionAsync&nbsp;method. For example,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncactionfilter.onactionexecutionasync\">OnActionExecutionAsync<\/a>:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleAsyncActionFilter : IAsyncActionFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public async Task OnActionExecutionAsync(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionExecutingContext context, ActionExecutionDelegate next)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something before the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await next();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something after the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>In the preceding code, the&nbsp;SampleAsyncActionFilter&nbsp;has an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutiondelegate\">ActionExecutionDelegate<\/a>,&nbsp;next, which executes the action method.<\/p>\n\n\n\n<p><strong>Multiple filter stages<\/strong><\/p>\n\n\n\n<p>Interfaces for multiple filter stages can be implemented in a single class. For example, the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionfilterattribute\">ActionFilterAttribute<\/a>&nbsp;class implements:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Synchronous:&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iactionfilter\">IActionFilter<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresultfilter\">IResultFilter<\/a><\/li>\n\n\n\n<li>Asynchronous:&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncactionfilter\">IAsyncActionFilter<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncresultfilter\">IAsyncResultFilter<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iorderedfilter\">IOrderedFilter<\/a><\/li>\n<\/ul>\n\n\n\n<p>Implement&nbsp;<strong>either<\/strong>&nbsp;the synchronous or the async version of a filter interface,&nbsp;<strong>not<\/strong>&nbsp;both. The runtime checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface&#8217;s method(s). If both asynchronous and synchronous interfaces are implemented in one class, only the async method is called. When using abstract classes like&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionfilterattribute\">ActionFilterAttribute<\/a>, override only the synchronous methods or the asynchronous methods for each filter type.<\/p>\n\n\n\n<p><strong>Built-in filter attributes<\/strong><\/p>\n\n\n\n<p>ASP.NET Core includes built-in attribute-based filters that can be subclassed and customized. For example, the following result filter adds a header to the response:<\/p>\n\n\n\n<p><a><\/a>C#Copy<\/p>\n\n\n\n<p>public class ResponseHeaderAttribute : ActionFilterAttribute<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly string _name;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly string _value;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public ResponseHeaderAttribute(string name, string value) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (_name, _value) = (name, value);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public override void OnResultExecuting(ResultExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.HttpContext.Response.Headers.Add(_name, _value);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnResultExecuting(context);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Attributes allow filters to accept arguments, as shown in the preceding example. Apply the&nbsp;ResponseHeaderAttribute&nbsp;to a controller or action method and specify the name and value of the HTTP header:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[ResponseHeader(&#8220;Filter-Header&#8221;, &#8220;Filter Value&#8221;)]<\/p>\n\n\n\n<p>public class ResponseHeaderController : ControllerBase<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content(&#8220;Examine the response headers using the F12 developer tools.&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; \/\/ &#8230;<\/p>\n\n\n\n<p>Use a tool such as the&nbsp;<a href=\"https:\/\/developer.mozilla.org\/docs\/Learn\/Common_questions\/What_are_browser_developer_tools\">browser developer tools<\/a>&nbsp;to examine the headers. Under&nbsp;<strong>Response Headers<\/strong>,&nbsp;filter-header: Filter Value&nbsp;is displayed.<\/p>\n\n\n\n<p>The following code applies&nbsp;ResponseHeaderAttribute&nbsp;to both a controller and an action:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[ResponseHeader(&#8220;Filter-Header&#8221;, &#8220;Filter Value&#8221;)]<\/p>\n\n\n\n<p>public class ResponseHeaderController : ControllerBase<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content(&#8220;Examine the response headers using the F12 developer tools.&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; \/\/ &#8230;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; [ResponseHeader(&#8220;Another-Filter-Header&#8221;, &#8220;Another Filter Value&#8221;)]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Multiple() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content(&#8220;Examine the response headers using the F12 developer tools.&#8221;);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Responses from the&nbsp;Multiple&nbsp;action include the following headers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>filter-header: Filter Value<\/li>\n\n\n\n<li>another-filter-header: Another Filter Value<\/li>\n<\/ul>\n\n\n\n<p>Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.<\/p>\n\n\n\n<p>Filter attributes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionfilterattribute\">ActionFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.exceptionfilterattribute\">ExceptionFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resultfilterattribute\">ResultFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.formatfilterattribute\">FormatFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute\">ServiceFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.typefilterattribute\">TypeFilterAttribute<\/a><\/li>\n<\/ul>\n\n\n\n<p>Filters cannot be applied to Razor Page handler methods. They can be applied either to the Razor Page model or globally.<\/p>\n\n\n\n<p><strong>Filter scopes and order of execution<\/strong><\/p>\n\n\n\n<p>A filter can be added to the pipeline at one of three&nbsp;<em>scopes<\/em>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using an attribute on a controller or Razor Page.<\/li>\n\n\n\n<li>Using an attribute on a controller action. Filter attributes cannot be applied to Razor Pages handler methods.<\/li>\n\n\n\n<li>Globally for all controllers, actions, and Razor Pages as shown in the following code:<\/li>\n<\/ul>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>var builder = WebApplication.CreateBuilder(args);<\/p>\n\n\n\n<p>\/\/ Add services to the container.<\/p>\n\n\n\n<p>builder.Services.AddControllersWithViews(options =&gt;<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; options.Filters.Add&lt;GlobalSampleActionFilter&gt;();<\/p>\n\n\n\n<p>});<\/p>\n\n\n\n<p><strong>Default order of execution<\/strong><\/p>\n\n\n\n<p>When there are multiple filters for a particular stage of the pipeline, scope determines the default order of filter execution. Global filters surround class filters, which in turn surround method filters.<\/p>\n\n\n\n<p>As a result of filter nesting, the&nbsp;<em>after<\/em>&nbsp;code of filters runs in the reverse order of the&nbsp;<em>before<\/em>&nbsp;code. The filter sequence:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The\u00a0<em>before<\/em>\u00a0code of global filters.<ul><li>The&nbsp;<em>before<\/em>&nbsp;code of controller filters.<ul><li>The&nbsp;<em>before<\/em>&nbsp;code of action method filters.<\/li><\/ul><ul><li>The&nbsp;<em>after<\/em>&nbsp;code of action method filters.<\/li><\/ul><\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>The&nbsp;<em>after<\/em>&nbsp;code of controller filters.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>The&nbsp;<em>after<\/em>&nbsp;code of global filters.<\/li>\n<\/ul>\n\n\n\n<p>The following example illustrates the order in which filter methods run for synchronous action filters:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><td><strong>Sequence<\/strong><\/td><td><strong>Filter scope<\/strong><\/td><td><strong>Filter method<\/strong><\/td><\/tr><\/thead><tbody><tr><td>1<\/td><td>Global<\/td><td>OnActionExecuting<\/td><\/tr><tr><td>2<\/td><td>Controller<\/td><td>OnActionExecuting<\/td><\/tr><tr><td>3<\/td><td>Action<\/td><td>OnActionExecuting<\/td><\/tr><tr><td>4<\/td><td>Action<\/td><td>OnActionExecuted<\/td><\/tr><tr><td>5<\/td><td>Controller<\/td><td>OnActionExecuted<\/td><\/tr><tr><td>6<\/td><td>Global<\/td><td>OnActionExecuted<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Controller level filters<\/strong><\/p>\n\n\n\n<p>Every controller that inherits from&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.controller\">Controller<\/a>&nbsp;includes the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.controller.onactionexecuting\">OnActionExecuting<\/a>,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.controller.onactionexecutionasync\">OnActionExecutionAsync<\/a>, and&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.controller.onactionexecuted\">OnActionExecuted<\/a>&nbsp;methods. These methods wrap the filters that run for a given action:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>OnActionExecuting&nbsp;runs before any of the action&#8217;s filters.<\/li>\n\n\n\n<li>OnActionExecuted&nbsp;runs after all of the action&#8217;s filters.<\/li>\n\n\n\n<li>OnActionExecutionAsync&nbsp;runs before any of the action&#8217;s filters. Code after a call to&nbsp;next&nbsp;runs after the action&#8217;s filters.<\/li>\n<\/ul>\n\n\n\n<p>The following&nbsp;ControllerFiltersController&nbsp;class:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Applies the&nbsp;SampleActionFilterAttribute&nbsp;([SampleActionFilter]) to the controller.<\/li>\n\n\n\n<li>Overrides&nbsp;OnActionExecuting&nbsp;and&nbsp;OnActionExecuted.<\/li>\n<\/ul>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[SampleActionFilter]<\/p>\n\n\n\n<p>public class ControllerFiltersController : Controller<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public override void OnActionExecuting(ActionExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuting)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnActionExecuting(context);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public override void OnActionExecuted(ActionExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuted)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnActionExecuted(context);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index()<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(ControllerFiltersController)}.{nameof(Index)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Content(&#8220;Check the Console.&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Navigating to&nbsp;https:\/\/localhost:&lt;port&gt;\/ControllerFilters&nbsp;runs the following code:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ControllerFiltersController.OnActionExecuting<ul><li>GlobalSampleActionFilter.OnActionExecuting<ul><li>SampleActionFilterAttribute.OnActionExecuting<ul><li>ControllerFiltersController.Index<\/li><\/ul><\/li><\/ul><ul><li>SampleActionFilterAttribute.OnActionExecuted<\/li><\/ul><\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>GlobalSampleActionFilter.OnActionExecuted<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>ControllerFiltersController.OnActionExecuted<\/li>\n<\/ul>\n\n\n\n<p>Controller level filters set the&nbsp;<a href=\"https:\/\/github.com\/dotnet\/AspNetCore\/blob\/main\/src\/Mvc\/Mvc.Core\/src\/Filters\/ControllerActionFilter.cs#L15-L17\">Order<\/a>&nbsp;property to&nbsp;int.MinValue. Controller level filters can&nbsp;<strong>not<\/strong>&nbsp;be set to run after filters applied to methods. Order is explained in the next section.<\/p>\n\n\n\n<p>For Razor Pages, see&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/razor-pages\/filter?view=aspnetcore-6.0#implement-razor-page-filters-by-overriding-filter-methods\">Implement Razor Page filters by overriding filter methods<\/a>.<\/p>\n\n\n\n<p><strong>Override the default order<\/strong><\/p>\n\n\n\n<p>The default sequence of execution can be overridden by implementing&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iorderedfilter\">IOrderedFilter<\/a>.&nbsp;IOrderedFilter&nbsp;exposes the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iorderedfilter.order#microsoft-aspnetcore-mvc-filters-iorderedfilter-order\">Order<\/a>&nbsp;property that takes precedence over scope to determine the order of execution. A filter with a lower&nbsp;Order&nbsp;value:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Runs the&nbsp;<em>before<\/em>&nbsp;code before that of a filter with a higher value of&nbsp;Order.<\/li>\n\n\n\n<li>Runs the&nbsp;<em>after<\/em>&nbsp;code after that of a filter with a higher&nbsp;Order&nbsp;value.<\/li>\n<\/ul>\n\n\n\n<p>In the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#controller-level-filters\">Controller level filters<\/a>&nbsp;example,&nbsp;GlobalSampleActionFilter&nbsp;has global scope so it runs before&nbsp;SampleActionFilterAttribute, which has controller scope. To make&nbsp;SampleActionFilterAttribute&nbsp;run first, set its order to&nbsp;int.MinValue:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[SampleActionFilter(Order = int.MinValue)]<\/p>\n\n\n\n<p>public class ControllerFiltersController : Controller<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; \/\/ &#8230;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>To make the global filter&nbsp;GlobalSampleActionFilter&nbsp;run first, set its&nbsp;Order&nbsp;to&nbsp;int.MinValue:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>builder.Services.AddControllersWithViews(options =&gt;<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; options.Filters.Add&lt;GlobalSampleActionFilter&gt;(int.MinValue);<\/p>\n\n\n\n<p>});<\/p>\n\n\n\n<p><strong>Cancellation and short-circuiting<\/strong><\/p>\n\n\n\n<p>The filter pipeline can be short-circuited by setting the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resourceexecutingcontext.result#microsoft-aspnetcore-mvc-filters-resourceexecutingcontext-result\">Result<\/a>&nbsp;property on the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resourceexecutingcontext\">ResourceExecutingContext<\/a>&nbsp;parameter provided to the filter method. For example, the following Resource filter prevents the rest of the pipeline from executing:<\/p>\n\n\n\n<p><a><\/a>C#Copy<\/p>\n\n\n\n<p>public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResourceExecuting(ResourceExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Result = new ContentResult<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content = nameof(ShortCircuitingResourceFilterAttribute)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResourceExecuted(ResourceExecutedContext context) { }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>In the following code, both the&nbsp;[ShortCircuitingResourceFilter]&nbsp;and the&nbsp;[ResponseHeader]&nbsp;filter target the&nbsp;Index&nbsp;action method. The&nbsp;ShortCircuitingResourceFilterAttribute&nbsp;filter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Runs first, because it&#8217;s a Resource Filter and&nbsp;ResponseHeaderAttribute&nbsp;is an Action Filter.<\/li>\n\n\n\n<li>Short-circuits the rest of the pipeline.<\/li>\n<\/ul>\n\n\n\n<p>Therefore the&nbsp;ResponseHeaderAttribute&nbsp;filter never runs for the&nbsp;Index&nbsp;action. This behavior would be the same if both filters were applied at the action method level, provided the&nbsp;ShortCircuitingResourceFilterAttribute&nbsp;ran first. The&nbsp;ShortCircuitingResourceFilterAttribute&nbsp;runs first because of its filter type:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[ResponseHeader(&#8220;Filter-Header&#8221;, &#8220;Filter Value&#8221;)]<\/p>\n\n\n\n<p>public class ShortCircuitingController : Controller<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; [ShortCircuitingResourceFilter]<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(ShortCircuitingController)}.{nameof(Index)}&#8221;);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p><strong>Dependency injection<\/strong><\/p>\n\n\n\n<p>Filters can be added by type or by instance. If an instance is added, that instance is used for every request. If a type is added, it&#8217;s type-activated. A type-activated filter means:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An instance is created for each request.<\/li>\n\n\n\n<li>Any constructor dependencies are populated by&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/dependency-injection?view=aspnetcore-6.0\">dependency injection<\/a>&nbsp;(DI).<\/li>\n<\/ul>\n\n\n\n<p>Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/dependency-injection?view=aspnetcore-6.0\">dependency injection<\/a>&nbsp;(DI). Constructor dependencies cannot be provided by DI because attributes must have their constructor parameters supplied where they&#8217;re applied.<\/p>\n\n\n\n<p>The following filters support constructor dependencies provided from DI:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute\">ServiceFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.typefilterattribute\">TypeFilterAttribute<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory\">IFilterFactory<\/a>&nbsp;implemented on the attribute.<\/li>\n<\/ul>\n\n\n\n<p>The preceding filters can be applied to a controller or an action.<\/p>\n\n\n\n<p>Loggers are available from DI. However, avoid creating and using filters purely for logging purposes. The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/logging\/?view=aspnetcore-6.0\">built-in framework logging<\/a>&nbsp;typically provides what&#8217;s needed for logging. Logging added to filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Should focus on business domain concerns or behavior specific to the filter.<\/li>\n\n\n\n<li>Should&nbsp;<strong>not<\/strong>&nbsp;log actions or other framework events. The built-in filters already log actions and framework events.<\/li>\n<\/ul>\n\n\n\n<p><strong>ServiceFilterAttribute<\/strong><\/p>\n\n\n\n<p>Service filter implementation types are registered in&nbsp;Program.cs. A&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute\">ServiceFilterAttribute<\/a>&nbsp;retrieves an instance of the filter from DI.<\/p>\n\n\n\n<p>The following code shows the&nbsp;LoggingResponseHeaderFilterService&nbsp;class, which uses DI:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class LoggingResponseHeaderFilterService : IResultFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly ILogger _logger;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public LoggingResponseHeaderFilterService(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ILogger&lt;LoggingResponseHeaderFilterService&gt; logger) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger = logger;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuting(ResultExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger.LogInformation(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuting)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.HttpContext.Response.Headers.Add(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameof(OnResultExecuting), nameof(LoggingResponseHeaderFilterService));<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuted(ResultExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger.LogInformation(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuted)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>In the following code,&nbsp;LoggingResponseHeaderFilterService&nbsp;is added to the DI container:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>builder.Services.AddScoped&lt;LoggingResponseHeaderFilterService&gt;();<\/p>\n\n\n\n<p>In the following code, the&nbsp;ServiceFilter&nbsp;attribute retrieves an instance of the&nbsp;LoggingResponseHeaderFilterService&nbsp;filter from DI:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[ServiceFilter(typeof(LoggingResponseHeaderFilterService))]<\/p>\n\n\n\n<p>public IActionResult WithServiceFilter() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterDependenciesController)}.{nameof(WithServiceFilter)}&#8221;);<\/p>\n\n\n\n<p>When using&nbsp;ServiceFilterAttribute, setting&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute.isreusable#microsoft-aspnetcore-mvc-servicefilterattribute-isreusable\">ServiceFilterAttribute.IsReusable<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provides a hint that the filter instance\u00a0<em>may<\/em>\u00a0be reused outside of the request scope it was created within. The ASP.NET Core runtime doesn&#8217;t guarantee:<ul><li>That a single instance of the filter will be created.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>The filter will not be re-requested from the DI container at some later point.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Shouldn&#8217;t be used with a filter that depends on services with a lifetime other than singleton.<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute\">ServiceFilterAttribute<\/a>&nbsp;implements&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory\">IFilterFactory<\/a>.&nbsp;IFilterFactory&nbsp;exposes the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory.createinstance\">CreateInstance<\/a>&nbsp;method for creating an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifiltermetadata\">IFilterMetadata<\/a>&nbsp;instance.&nbsp;CreateInstance&nbsp;loads the specified type from DI.<\/p>\n\n\n\n<p><strong>TypeFilterAttribute<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.typefilterattribute\">TypeFilterAttribute<\/a>&nbsp;is similar to&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.servicefilterattribute\">ServiceFilterAttribute<\/a>, but its type isn&#8217;t resolved directly from the DI container. It instantiates the type by using&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.extensions.dependencyinjection.objectfactory\">Microsoft.Extensions.DependencyInjection.ObjectFactory<\/a>.<\/p>\n\n\n\n<p>Because&nbsp;TypeFilterAttribute&nbsp;types aren&#8217;t resolved directly from the DI container:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Types that are referenced using the&nbsp;TypeFilterAttribute&nbsp;don&#8217;t need to be registered with the DI container. They do have their dependencies fulfilled by the DI container.<\/li>\n\n\n\n<li>TypeFilterAttribute&nbsp;can optionally accept constructor arguments for the type.<\/li>\n<\/ul>\n\n\n\n<p>When using&nbsp;TypeFilterAttribute, setting&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.typefilterattribute.isreusable#microsoft-aspnetcore-mvc-typefilterattribute-isreusable\">TypeFilterAttribute.IsReusable<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provides hint that the filter instance&nbsp;<em>may<\/em>&nbsp;be reused outside of the request scope it was created within. The ASP.NET Core runtime provides no guarantees that a single instance of the filter will be created.<\/li>\n\n\n\n<li>Should not be used with a filter that depends on services with a lifetime other than singleton.<\/li>\n<\/ul>\n\n\n\n<p>The following example shows how to pass arguments to a type using&nbsp;TypeFilterAttribute:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[TypeFilter(typeof(LoggingResponseHeaderFilter),<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Arguments = new object[] { &#8220;Filter-Header&#8221;, &#8220;Filter Value&#8221; })]<\/p>\n\n\n\n<p>public IActionResult WithTypeFilter() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterDependenciesController)}.{nameof(WithTypeFilter)}&#8221;);<\/p>\n\n\n\n<p><strong>Authorization filters<\/strong><\/p>\n\n\n\n<p>Authorization filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Are the first filters run in the filter pipeline.<\/li>\n\n\n\n<li>Control access to action methods.<\/li>\n\n\n\n<li>Have a before method, but no after method.<\/li>\n<\/ul>\n\n\n\n<p>Custom authorization filters require a custom authorization framework. Prefer configuring the authorization policies or writing a custom authorization policy over writing a custom filter. The built-in authorization filter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Calls the authorization system.<\/li>\n\n\n\n<li>Does not authorize requests.<\/li>\n<\/ul>\n\n\n\n<p>Do&nbsp;<strong>not<\/strong>&nbsp;throw exceptions within authorization filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The exception will not be handled.<\/li>\n\n\n\n<li>Exception filters will not handle the exception.<\/li>\n<\/ul>\n\n\n\n<p>Consider issuing a challenge when an exception occurs in an authorization filter.<\/p>\n\n\n\n<p>Learn more about&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/introduction?view=aspnetcore-6.0\">Authorization<\/a>.<\/p>\n\n\n\n<p><strong>Resource filters<\/strong><\/p>\n\n\n\n<p>Resource filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement either the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresourcefilter\">IResourceFilter<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncresourcefilter\">IAsyncResourceFilter<\/a>&nbsp;interface.<\/li>\n\n\n\n<li>Execution wraps most of the filter pipeline.<\/li>\n\n\n\n<li>Only&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#authorization-filters\">Authorization filters<\/a>&nbsp;run before resource filters.<\/li>\n<\/ul>\n\n\n\n<p>Resource filters are useful to short-circuit most of the pipeline. For example, a caching filter can avoid the rest of the pipeline on a cache hit.<\/p>\n\n\n\n<p>Resource filter examples:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#short-circuiting-resource-filter\">The short-circuiting resource filter<\/a>&nbsp;shown previously.<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/aspnet\/Entropy\/blob\/master\/samples\/Mvc.FileUpload\/Filters\/DisableFormValueModelBindingAttribute.cs\">DisableFormValueModelBindingAttribute<\/a>:<ul><li>Prevents model binding from accessing the form data.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>Used for large file uploads to prevent the form data from being read into memory.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>Action filters<\/strong><\/p>\n\n\n\n<p>Action filters do&nbsp;<strong>not<\/strong>&nbsp;apply to Razor Pages. Razor Pages supports&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ipagefilter\">IPageFilter<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncpagefilter\">IAsyncPageFilter<\/a>. For more information, see&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/razor-pages\/filter?view=aspnetcore-6.0\">Filter methods for Razor Pages<\/a>.<\/p>\n\n\n\n<p>Action filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement either the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iactionfilter\">IActionFilter<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncactionfilter\">IAsyncActionFilter<\/a>&nbsp;interface.<\/li>\n\n\n\n<li>Their execution surrounds the execution of action methods.<\/li>\n<\/ul>\n\n\n\n<p>The following code shows a sample action filter:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleActionFilter : IActionFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnActionExecuting(ActionExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something before the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnActionExecuted(ActionExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something after the action executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutingcontext\">ActionExecutingContext<\/a>&nbsp;provides the following properties:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutingcontext.actionarguments#microsoft-aspnetcore-mvc-filters-actionexecutingcontext-actionarguments\">ActionArguments<\/a>&nbsp;&#8211; enables reading the inputs to an action method.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.controller\">Controller<\/a>&nbsp;&#8211; enables manipulating the controller instance.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutingcontext.result\">Result<\/a>&nbsp;&#8211; setting&nbsp;Result&nbsp;short-circuits execution of the action method and subsequent action filters.<\/li>\n<\/ul>\n\n\n\n<p>Throwing an exception in an action method:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prevents running of subsequent filters.<\/li>\n\n\n\n<li>Unlike setting&nbsp;Result, is treated as a failure instead of a successful result.<\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext\">ActionExecutedContext<\/a>&nbsp;provides&nbsp;Controller&nbsp;and&nbsp;Result&nbsp;plus the following properties:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext.canceled\">Canceled<\/a>&nbsp;&#8211; True if the action execution was short-circuited by another filter.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext.exception\">Exception<\/a>\u00a0&#8211; Non-null if the action or a previously run action filter threw an exception. Setting this property to null:<ul><li>Effectively handles the exception.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>Result&nbsp;is executed as if it was returned from the action method.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>For an&nbsp;IAsyncActionFilter, a call to the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutiondelegate\">ActionExecutionDelegate<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Executes any subsequent action filters and the action method.<\/li>\n\n\n\n<li>Returns&nbsp;ActionExecutedContext.<\/li>\n<\/ul>\n\n\n\n<p>To short-circuit, assign&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutingcontext.result#microsoft-aspnetcore-mvc-filters-actionexecutingcontext-result\">Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.Result<\/a>&nbsp;to a result instance and don&#8217;t call&nbsp;next&nbsp;(the&nbsp;ActionExecutionDelegate).<\/p>\n\n\n\n<p>The framework provides an abstract&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionfilterattribute\">ActionFilterAttribute<\/a>&nbsp;that can be subclassed.<\/p>\n\n\n\n<p>The&nbsp;OnActionExecuting&nbsp;action filter can be used to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Validate model state.<\/li>\n\n\n\n<li>Return an error if the state is invalid.<\/li>\n<\/ul>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class ValidateModelAttribute : ActionFilterAttribute<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public override void OnActionExecuting(ActionExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!context.ModelState.IsValid)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Result = new BadRequestObjectResult(context.ModelState);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p><strong>&nbsp;Note<\/strong><\/p>\n\n\n\n<p>Controllers annotated with the&nbsp;[ApiController]&nbsp;attribute automatically validate model state and return a 400 response. For more information, see&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/web-api\/?view=aspnetcore-6.0#automatic-http-400-responses\"><strong>Automatic HTTP 400 responses<\/strong><\/a>.<\/p>\n\n\n\n<p>The&nbsp;OnActionExecuted&nbsp;method runs after the action method:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>And can see and manipulate the results of the action through the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext.result#microsoft-aspnetcore-mvc-filters-actionexecutedcontext-result\">Result<\/a>&nbsp;property.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext.canceled#microsoft-aspnetcore-mvc-filters-actionexecutedcontext-canceled\">Canceled<\/a>&nbsp;is set to true if the action execution was short-circuited by another filter.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.actionexecutedcontext.exception#microsoft-aspnetcore-mvc-filters-actionexecutedcontext-exception\">Exception<\/a>\u00a0is set to a non-null value if the action or a subsequent action filter threw an exception. Setting\u00a0Exception\u00a0to null:<ul><li>Effectively handles an exception.<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>ActionExecutedContext.Result&nbsp;is executed as if it were returned normally from the action method.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>Exception filters<\/strong><\/p>\n\n\n\n<p>Exception filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iexceptionfilter\">IExceptionFilter<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncexceptionfilter\">IAsyncExceptionFilter<\/a>.<\/li>\n\n\n\n<li>Can be used to implement common error handling policies.<\/li>\n<\/ul>\n\n\n\n<p>The following sample exception filter displays details about exceptions that occur when the app is in development:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleExceptionFilter : IExceptionFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly IHostEnvironment _hostEnvironment;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public SampleExceptionFilter(IHostEnvironment hostEnvironment) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _hostEnvironment = hostEnvironment;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnException(ExceptionContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!_hostEnvironment.IsDevelopment())<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Don&#8217;t display exception details unless running in Development.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Result = new ContentResult<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Content = context.Exception.ToString()<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>The following code tests the exception filter:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[TypeFilter(typeof(SampleExceptionFilter))]<\/p>\n\n\n\n<p>public class ExceptionController : Controller<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(ExceptionController)}.{nameof(Index)}&#8221;);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Exception filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Don&#8217;t have before and after events.<\/li>\n\n\n\n<li>Implement&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iexceptionfilter.onexception\">OnException<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncexceptionfilter.onexceptionasync\">OnExceptionAsync<\/a>.<\/li>\n\n\n\n<li>Handle unhandled exceptions that occur in Razor Page or controller creation,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/models\/model-binding?view=aspnetcore-6.0\">model binding<\/a>, action filters, or action methods.<\/li>\n\n\n\n<li>Do&nbsp;<strong>not<\/strong>&nbsp;catch exceptions that occur in resource filters, result filters, or MVC result execution.<\/li>\n<\/ul>\n\n\n\n<p>To handle an exception, set the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.exceptioncontext.exceptionhandled\">ExceptionHandled<\/a>&nbsp;property to&nbsp;true&nbsp;or assign the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.exceptioncontext.result\">Result<\/a>&nbsp;property. This stops propagation of the exception. An exception filter can&#8217;t turn an exception into a &#8220;success&#8221;. Only an action filter can do that.<\/p>\n\n\n\n<p>Exception filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Are good for trapping exceptions that occur within actions.<\/li>\n\n\n\n<li>Are not as flexible as error handling middleware.<\/li>\n<\/ul>\n\n\n\n<p>Prefer middleware for exception handling. Use exception filters only where error handling&nbsp;<em>differs<\/em>&nbsp;based on which action method is called. For example, an app might have action methods for both API endpoints and for views\/HTML. The API endpoints could return error information as JSON, while the view-based actions could return an error page as HTML.<\/p>\n\n\n\n<p><strong>Result filters<\/strong><\/p>\n\n\n\n<p>Result filters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement an interface:<ul><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresultfilter\">IResultFilter<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncresultfilter\">IAsyncResultFilter<\/a><\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ialwaysrunresultfilter\">IAlwaysRunResultFilter<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncalwaysrunresultfilter\">IAsyncAlwaysRunResultFilter<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Their execution surrounds the execution of action results.<\/li>\n<\/ul>\n\n\n\n<p><strong>IResultFilter and IAsyncResultFilter<\/strong><\/p>\n\n\n\n<p>The following code shows a sample result filter:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleResultFilter : IResultFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuting(ResultExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something before the result executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuted(ResultExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ Do something after the result executes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>The kind of result being executed depends on the action. An action returning a view includes all razor processing as part of the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.viewresult\">ViewResult<\/a>&nbsp;being executed. An API method might perform some serialization as part of the execution of the result. Learn more about&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/actions?view=aspnetcore-6.0\">action results<\/a>.<\/p>\n\n\n\n<p>Result filters are only executed when an action or action filter produces an action result. Result filters are not executed when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An authorization filter or resource filter short-circuits the pipeline.<\/li>\n\n\n\n<li>An exception filter handles an exception by producing an action result.<\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresultfilter.onresultexecuting\">Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting<\/a>&nbsp;method can short-circuit execution of the action result and subsequent result filters by setting&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resultexecutingcontext.cancel#microsoft-aspnetcore-mvc-filters-resultexecutingcontext-cancel\">Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel<\/a>&nbsp;to&nbsp;true. Write to the response object when short-circuiting to avoid generating an empty response. Throwing an exception in&nbsp;IResultFilter.OnResultExecuting:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prevents execution of the action result and subsequent filters.<\/li>\n\n\n\n<li>Is treated as a failure instead of a successful result.<\/li>\n<\/ul>\n\n\n\n<p>When the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresultfilter.onresultexecuted\">Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted<\/a>&nbsp;method runs, the response has probably already been sent to the client. If the response has already been sent to the client, it cannot be changed.<\/p>\n\n\n\n<p>ResultExecutedContext.Canceled&nbsp;is set to&nbsp;true&nbsp;if the action result execution was short-circuited by another filter.<\/p>\n\n\n\n<p>ResultExecutedContext.Exception&nbsp;is set to a non-null value if the action result or a subsequent result filter threw an exception. Setting&nbsp;Exception&nbsp;to null effectively handles an exception and prevents the exception from being thrown again later in the pipeline. There is no reliable way to write data to a response when handling an exception in a result filter. If the headers have been flushed to the client when an action result throws an exception, there&#8217;s no reliable mechanism to send a failure code.<\/p>\n\n\n\n<p>For an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncresultfilter\">IAsyncResultFilter<\/a>, a call to&nbsp;await next&nbsp;on the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resultexecutiondelegate\">ResultExecutionDelegate<\/a>&nbsp;executes any subsequent result filters and the action result. To short-circuit, set&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.resultexecutingcontext.cancel#microsoft-aspnetcore-mvc-filters-resultexecutingcontext-cancel\">ResultExecutingContext.Cancel<\/a>&nbsp;to&nbsp;true&nbsp;and don&#8217;t call the&nbsp;ResultExecutionDelegate:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleAsyncResultFilter : IAsyncResultFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public async Task OnResultExecutionAsync(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultExecutingContext context, ResultExecutionDelegate next)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (context.Result is not EmptyResult)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await next();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Cancel = true;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>The framework provides an abstract&nbsp;ResultFilterAttribute&nbsp;that can be subclassed. The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/mvc\/controllers\/filters?view=aspnetcore-6.0#response-header-attribute\">ResponseHeaderAttribute<\/a>&nbsp;class shown previously is an example of a result filter attribute.<\/p>\n\n\n\n<p><strong>IAlwaysRunResultFilter and IAsyncAlwaysRunResultFilter<\/strong><\/p>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ialwaysrunresultfilter\">IAlwaysRunResultFilter<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iasyncalwaysrunresultfilter\">IAsyncAlwaysRunResultFilter<\/a>&nbsp;interfaces declare an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.iresultfilter\">IResultFilter<\/a>&nbsp;implementation that runs for all action results. This includes action results produced by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Authorization filters and resource filters that short-circuit.<\/li>\n\n\n\n<li>Exception filters.<\/li>\n<\/ul>\n\n\n\n<p>For example, the following filter always runs and sets an action result (<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.objectresult\">ObjectResult<\/a>) with a&nbsp;<em>422 Unprocessable Entity<\/em>&nbsp;status code when content negotiation fails:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class UnprocessableResultFilter : IAlwaysRunResultFilter<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuting(ResultExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (context.Result is StatusCodeResult statusCodeResult<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; statusCodeResult.StatusCode == StatusCodes.Status415UnsupportedMediaType)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Result = new ObjectResult(&#8220;Unprocessable&#8221;)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StatusCode = StatusCodes.Status422UnprocessableEntity<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void OnResultExecuted(ResultExecutedContext context) { }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p><strong>IFilterFactory<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory\">IFilterFactory<\/a>&nbsp;implements&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifiltermetadata\">IFilterMetadata<\/a>. Therefore, an&nbsp;IFilterFactory&nbsp;instance can be used as an&nbsp;IFilterMetadata&nbsp;instance anywhere in the filter pipeline. When the runtime prepares to invoke the filter, it attempts to cast it to an&nbsp;IFilterFactory. If that cast succeeds, the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory.createinstance\">CreateInstance<\/a>&nbsp;method is called to create the&nbsp;IFilterMetadata&nbsp;instance that is invoked. This provides a flexible design, since the precise filter pipeline doesn&#8217;t need to be set explicitly when the app starts.<\/p>\n\n\n\n<p>IFilterFactory.IsReusable:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Is a hint by the factory that the filter instance created by the factory may be reused outside of the request scope it was created within.<\/li>\n\n\n\n<li>Should&nbsp;<strong><em>not<\/em><\/strong>&nbsp;be used with a filter that depends on services with a lifetime other than singleton.<\/li>\n<\/ul>\n\n\n\n<p>The ASP.NET Core runtime doesn&#8217;t guarantee:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>That a single instance of the filter will be created.<\/li>\n\n\n\n<li>The filter will not be re-requested from the DI container at some later point.<\/li>\n<\/ul>\n\n\n\n<p><strong>&nbsp;Warning<\/strong><\/p>\n\n\n\n<p>Only configure&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory.isreusable#microsoft-aspnetcore-mvc-filters-ifilterfactory-isreusable\"><strong>IFilterFactory.IsReusable<\/strong><\/a>&nbsp;to return&nbsp;true&nbsp;if the source of the filters is unambiguous, the filters are stateless, and the filters are safe to use across multiple HTTP requests. For instance, don&#8217;t return filters from DI that are registered as scoped or transient if&nbsp;IFilterFactory.IsReusable&nbsp;returns&nbsp;true.<\/p>\n\n\n\n<p>IFilterFactory&nbsp;can be implemented using custom attribute implementations as another approach to creating filters:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class ResponseHeaderFilterFactory : Attribute, IFilterFactory<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public bool IsReusable =&gt; false;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new InternalResponseHeaderFilter();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private class InternalResponseHeaderFilter : IActionFilter<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void OnActionExecuting(ActionExecutingContext context) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.HttpContext.Response.Headers.Add(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameof(OnActionExecuting), nameof(InternalResponseHeaderFilter));<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void OnActionExecuted(ActionExecutedContext context) { }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>The filter is applied in the following code:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[ResponseHeaderFilterFactory]<\/p>\n\n\n\n<p>public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterFactoryController)}.{nameof(Index)}&#8221;);<\/p>\n\n\n\n<p><strong>IFilterFactory implemented on an attribute<\/strong><\/p>\n\n\n\n<p>Filters that implement&nbsp;IFilterFactory&nbsp;are useful for filters that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Don&#8217;t require passing parameters.<\/li>\n\n\n\n<li>Have constructor dependencies that need to be filled by DI.<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.typefilterattribute\">TypeFilterAttribute<\/a>&nbsp;implements&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory\">IFilterFactory<\/a>.&nbsp;IFilterFactory&nbsp;exposes the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifilterfactory.createinstance\">CreateInstance<\/a>&nbsp;method for creating an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.filters.ifiltermetadata\">IFilterMetadata<\/a>&nbsp;instance.&nbsp;CreateInstance&nbsp;loads the specified type from the services container (DI).<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class SampleActionTypeFilterAttribute : TypeFilterAttribute<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public SampleActionTypeFilterAttribute()<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : base(typeof(InternalSampleActionFilter)) { }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private class InternalSampleActionFilter : IActionFilter<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private readonly ILogger&lt;InternalSampleActionFilter&gt; _logger;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public InternalSampleActionFilter(ILogger&lt;InternalSampleActionFilter&gt; logger) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger = logger;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void OnActionExecuting(ActionExecutingContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger.LogInformation(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuting)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void OnActionExecuted(ActionExecutedContext context)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger.LogInformation(<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $&#8221;- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuted)}&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>The following code shows three approaches to applying the filter:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[SampleActionTypeFilter]<\/p>\n\n\n\n<p>public IActionResult WithDirectAttribute() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterFactoryController)}.{nameof(WithDirectAttribute)}&#8221;);<\/p>\n\n\n\n<p>[TypeFilter(typeof(SampleActionTypeFilterAttribute))]<\/p>\n\n\n\n<p>public IActionResult WithTypeFilterAttribute() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterFactoryController)}.{nameof(WithTypeFilterAttribute)}&#8221;);<\/p>\n\n\n\n<p>[ServiceFilter(typeof(SampleActionTypeFilterAttribute))]<\/p>\n\n\n\n<p>public IActionResult WithServiceFilterAttribute() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterFactoryController)}.{nameof(WithServiceFilterAttribute)}&#8221;);<\/p>\n\n\n\n<p>In the preceding code, the first approach to applying the filter is preferred.<\/p>\n\n\n\n<p><strong>Use middleware in the filter pipeline<\/strong><\/p>\n\n\n\n<p>Resource filters work like&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/middleware\/?view=aspnetcore-6.0\">middleware<\/a>&nbsp;in that they surround the execution of everything that comes later in the pipeline. But filters differ from middleware in that they&#8217;re part of the runtime, which means that they have access to context and constructs.<\/p>\n\n\n\n<p>To use middleware as a filter, create a type with a&nbsp;Configure&nbsp;method that specifies the middleware to inject into the filter pipeline. The following example uses middleware to set a response header:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>public class FilterMiddlewarePipeline<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public void Configure(IApplicationBuilder app)<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app.Use(async (context, next) =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Response.Headers.Add(&#8220;Pipeline&#8221;, &#8220;Middleware&#8221;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await next();<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Use the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.mvc.middlewarefilterattribute\">MiddlewareFilterAttribute<\/a>&nbsp;to run the middleware:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<p>[MiddlewareFilter(typeof(FilterMiddlewarePipeline))]<\/p>\n\n\n\n<p>public class FilterMiddlewareController : Controller<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public IActionResult Index() =&gt;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Content($&#8221;- {nameof(FilterMiddlewareController)}.{nameof(Index)}&#8221;);<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 Filters in ASP.NET Core Filters&nbsp;in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Custom filters can be created to handle cross-cutting concerns. Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Filters avoid duplicating code. For example, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[12,13,11,1],"tags":[],"class_list":["post-1855","post","type-post","status-publish","format-standard","hentry","category-asp-net","category-asp-net-core","category-csharp","category-uncategorized"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"http:\/\/waqar-arshad.com\/index.php\/author\/waqar_29_1\/"},"uagb_comment_info":24,"uagb_excerpt":"1 Filters in ASP.NET Core Filters&nbsp;in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Custom filters can be created to handle cross-cutting concerns. Examples of cross-cutting concerns include error handling, caching, configuration, authorization, and logging. Filters avoid duplicating code. For example,&hellip;","_links":{"self":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/comments?post=1855"}],"version-history":[{"count":1,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1855\/revisions"}],"predecessor-version":[{"id":1858,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1855\/revisions\/1858"}],"wp:attachment":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/media?parent=1855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/categories?post=1855"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/tags?post=1855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}