Filters in ASP.NET Core (转自MSDN)
Filters in ASP.NET Core MVC allow you to run code before or after specific stages in the request processing pipeline.
Important This topic does not apply to Razor Pages. ASP.NET Core 2.1 and later supports IPageFilter and IAsyncPageFilterfor Razor Pages. For more information, see Filter methods for Razor Pages.
Built-in filters handle tasks such as:
- Authorization (preventing access to resources a user isn't authorized for).
- Ensuring that all requests use HTTPS.
- Response caching (short-circuiting the request pipeline to return a cached response).
Custom filters can be created to handle cross-cutting concerns. Filters can avoid duplicating code across actions. For example, an error handling exception filter could consolidate error handling.
View or download sample from GitHub.
How do filters work?
Filters run within the MVC action invocation pipeline, sometimes referred to as the filter pipeline. The filter pipeline runs after MVC selects the action to execute.
Filter types
Each filter type is executed at a different stage in the filter pipeline.
- Authorization filters run first and are used to determine whether the current user is authorized for the current request. They can short-circuit the pipeline if a request is unauthorized.
- Resource filters are the first to handle a request after authorization. They can run code before the rest of the filter pipeline, and after the rest of the pipeline has completed. They're useful to implement caching or otherwise short-circuit the filter pipeline for performance reasons. They run before model binding, so they can influence model binding.
- Action filters can run code immediately before and after an individual action method is called. They can be used to manipulate the arguments passed into an action and the result returned from the action.
- Exception filters are used to apply global policies to unhandled exceptions that occur before anything has been written to the response body.
- Result filters can run code immediately before and after the execution of individual action results. They run only when the action method has executed successfully. They are useful for logic that must surround view or formatter execution.
The following diagram shows how these filter types interact in the filter pipeline.
Implementation
Filters support both synchronous and asynchronous implementations through different interface definitions.
Synchronous filters that can run code both before and after their pipeline stage define OnStageExecuting and OnStageExecuted methods. For example, OnActionExecuting is called before the action method is called, and OnActionExecuted is called after the action method returns.
using FiltersSample.Helper;
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters
{
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
} public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
}
Asynchronous filters define a single OnStageExecutionAsync method. This method takes a FilterTypeExecutionDelegate delegate which executes the filter's pipeline stage. For example, ActionExecutionDelegate calls the action method or next action filter, and you can execute code before and after you call it.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters
{
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
// do something before the action executes
var resultContext = await next();
// do something after the action executes; resultContext.Result will be set
}
}
}
You can implement interfaces for multiple filter stages in a single class. For example, the ActionFilterAttributeclass implements IActionFilter, IResultFilter, and their async equivalents.
Note
Implement either the synchronous or the async version of a filter interface, not both. The framework checks first to see if the filter implements the async interface, and if so, it calls that. If not, it calls the synchronous interface's method(s). If you were to implement both interfaces on one class, only the async method would be called. When using abstract classes like ActionFilterAttributeyou would override only the synchronous methods or the async method for each filter type.
IFilterFactory
IFilterFactory implements IFilterMetadata. Therefore, an IFilterFactory instance can be used as an IFilterMetadata instance anywhere in the filter pipeline. When the framework prepares to invoke the filter, it attempts to cast it to an IFilterFactory. If that cast succeeds, the CreateInstancemethod is called to create the IFilterMetadata instance that will be invoked. This provides a flexible design, since the precise filter pipeline doesn't need to be set explicitly when the app starts.
You can implement IFilterFactory on your own attribute implementations as another approach to creating filters:
public class AddHeaderWithFactoryAttribute : Attribute, IFilterFactory
{
// Implement IFilterFactory
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return new InternalAddHeaderFilter();
} private class InternalAddHeaderFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(
"Internal", new string[] { "Header Added" });
} public void OnResultExecuted(ResultExecutedContext context)
{
}
} public bool IsReusable
{
get
{
return false;
}
}
}
Built-in filter attributes
The framework includes built-in attribute-based filters that you can subclass and customize. For example, the following Result filter adds a header to the response.
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters
{
public class AddHeaderAttribute : ResultFilterAttribute
{
private readonly string _name;
private readonly string _value; public AddHeaderAttribute(string name, string value)
{
_name = name;
_value = value;
} public override void OnResultExecuting(ResultExecutingContext context)
{
context.HttpContext.Response.Headers.Add(
_name, new string[] { _value });
base.OnResultExecuting(context);
}
}
}
Attributes allow filters to accept arguments, as shown in the example above. You would add this attribute to a controller or action method and specify the name and value of the HTTP header:
[AddHeader("Author", "Steve Smith @ardalis")]
public class SampleController : Controller
{
public IActionResult Index()
{
return Content("Examine the headers using developer tools.");
} [ShortCircuitingResourceFilter]
public IActionResult SomeResource()
{
return Content("Successful access to resource - header should be set.");
}
The result of the Index action is shown below - the response headers are displayed on the bottom right.
Several of the filter interfaces have corresponding attributes that can be used as base classes for custom implementations.
Filter attributes:
- ActionFilterAttribute
- ExceptionFilterAttribute
- ResultFilterAttribute
- FormatFilterAttribute
- ServiceFilterAttribute
- TypeFilterAttribute
TypeFilterAttribute and ServiceFilterAttribute are explained later in this article.
Filter scopes and order of execution
A filter can be added to the pipeline at one of three scopes. You can add a filter to a particular action method or to a controller class by using an attribute. Or you can register a filter globally for all controllers and actions. Filters are added globally by adding it to the MvcOptions.Filters collection in ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
"Result filter added to MvcOptions.Filters")); // an instance
options.Filters.Add(typeof(SampleActionFilter)); // by type
options.Filters.Add(new SampleGlobalActionFilter()); // an instance
}); services.AddScoped<AddHeaderFilterWithDi>();
}
Default order of execution
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. This is sometimes referred to as "Russian doll" nesting, as each increase in scope is wrapped around the previous scope, like a nesting doll. You generally get the desired overriding behavior without having to explicitly determine ordering.
As a result of this nesting, the after code of filters runs in the reverse order of the before code. The sequence looks like this:
- The before code of filters applied globally
- The before code of filters applied to controllers
- The before code of filters applied to action methods
- The after code of filters applied to action methods
- The after code of filters applied to controllers
- The before code of filters applied to controllers
- The after code of filters applied globally
Here's an example that illustrates the order in which filter methods are called for synchronous Action filters.
Sequence | Filter scope | Filter method |
---|---|---|
1 | Global | OnActionExecuting |
2 | Controller | OnActionExecuting |
3 | Method | OnActionExecuting |
4 | Method | OnActionExecuted |
5 | Controller | OnActionExecuted |
6 | Global | OnActionExecuted |
This sequence shows:
- The method filter is nested within the controller filter.
- The controller filter is nested within the global filter.
To put it another way, if you're inside an async filter's OnStageExecutionAsync method, all of the filters with a tighter scope run while your code is on the stack.
Note
Every controller that inherits from the Controller base class includes OnActionExecuting and OnActionExecuted methods. These methods wrap the filters that run for a given action: OnActionExecuting is called before any of the filters, and OnActionExecuted is called after all of the filters.
Overriding the default order
You can override the default sequence of execution by implementing IOrderedFilter. This interface exposes an Order property that takes precedence over scope to determine the order of execution. A filter with a lower Order value will have its before code executed before that of a filter with a higher value of Order. A filter with a lower Order value will have its after code executed after that of a filter with a higher Order value. You can set the Order property by using a constructor parameter:
[MyFilter(Name = "Controller Level Attribute", Order=)]
If you have the same 3 Action filters shown in the preceding example but set the Order property of the controller and global filters to 1 and 2 respectively, the order of execution would be reversed.
Sequence | Filter scope | Order property |
Filter method |
---|---|---|---|
1 | Method | 0 | OnActionExecuting |
2 | Controller | 1 | OnActionExecuting |
3 | Global | 2 | OnActionExecuting |
4 | Global | 2 | OnActionExecuted |
5 | Controller | 1 | OnActionExecuted |
6 | Method | 0 | OnActionExecuted |
The Order property trumps scope when determining the order in which filters will run. Filters are sorted first by order, then scope is used to break ties. All of the built-in filters implement IOrderedFilter and set the default Order value to 0. For built-in filters, scope determines order unless you set Order to a non-zero value.
Cancellation and short circuiting
You can short-circuit the filter pipeline at any point by setting the Result property on the context parameter provided to the filter method. For instance, the following Resource filter prevents the rest of the pipeline from executing.
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters
{
public class ShortCircuitingResourceFilterAttribute : Attribute,
IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
context.Result = new ContentResult()
{
Content = "Resource unavailable - header should not be set"
};
} public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
}
In the following code, both the ShortCircuitingResourceFilter and the AddHeader filter target the SomeResource action method. The ShortCircuitingResourceFilter:
- Runs first, because it's a Resource Filter and AddHeader is an Action Filter.
- Short-circuits the rest of the pipeline.
Therefore the AddHeader filter never runs for the SomeResource action. This behavior would be the same if both filters were applied at the action method level, provided the ShortCircuitingResourceFilter ran first. The ShortCircuitingResourceFilter runs first because of its filter type, or by explicit use of Order property.
[AddHeader("Author", "Steve Smith @ardalis")]
public class SampleController : Controller
{
public IActionResult Index()
{
return Content("Examine the headers using developer tools.");
} [ShortCircuitingResourceFilter]
public IActionResult SomeResource()
{
return Content("Successful access to resource - header should be set.");
}
Dependency injection
Filters can be added by type or by instance. If you add an instance, that instance will be used for every request. If you add a type, it will be type-activated, meaning an instance will be created for each request and any constructor dependencies will be populated by dependency injection (DI). Adding a filter by type is equivalent to filters.Add(new TypeFilterAttribute(typeof(MyFilter))).
Filters that are implemented as attributes and added directly to controller classes or action methods cannot have constructor dependencies provided by dependency injection (DI). This is because attributes must have their constructor parameters supplied where they're applied. This is a limitation of how attributes work.
If your filters have dependencies that you need to access from DI, there are several supported approaches. You can apply your filter to a class or action method using one of the following:
- ServiceFilterAttribute
- TypeFilterAttribute
- IFilterFactory implemented on your attribute
Note
One dependency you might want to get from DI is a logger. However, avoid creating and using filters purely for logging purposes, since the built-in framework logging features may already provide what you need. If you're going to add logging to your filters, it should focus on business domain concerns or behavior specific to your filter, rather than MVC actions or other framework events.
ServiceFilterAttribute
Service filter implementation types are registered in DI. A ServiceFilterAttribute retrieves an instance of the filter from DI. Add the ServiceFilterAttribute to the container in Startup.ConfigureServices, and reference it in a [ServiceFilter] attribute:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
"Result filter added to MvcOptions.Filters")); // an instance
options.Filters.Add(typeof(SampleActionFilter)); // by type
options.Filters.Add(new SampleGlobalActionFilter()); // an instance
}); services.AddScoped<AddHeaderFilterWithDi>();
}
[ServiceFilter(typeof(AddHeaderFilterWithDi))]
public IActionResult Index()
{
return View();
}
When using ServiceFilterAttribute, setting IsReusable is a hint that the filter instance may be reused outside of the request scope it was created within. The framework provides no guarantees that a single instance of the filter will be created or the filter will not be re-requested from the DI container at some later point. Avoid using IsReusable when using a filter that depends on services with a lifetime other than singleton.
Using ServiceFilterAttribute without registering the filter type results in an exception:
System.InvalidOperationException: No service for type
'FiltersSample.Filters.AddHeaderFilterWithDI' has been registered.
ServiceFilterAttribute implements IFilterFactory. IFilterFactory exposes the CreateInstance method for creating an IFilterMetadata instance. The CreateInstance method loads the specified type from the services container (DI).
TypeFilterAttribute
TypeFilterAttribute is similar to ServiceFilterAttribute, but its type isn't resolved directly from the DI container. It instantiates the type by using
Microsoft.Extensions.DependencyInjection.ObjectFactory.
Because of this difference:
- Types that are referenced using the TypeFilterAttribute don't need to be registered with the container first. They do have their dependencies fulfilled by the container.
- TypeFilterAttribute can optionally accept constructor arguments for the type.
When using TypeFilterAttribute, setting IsReusable is a hint that the filter instance may be reused outside of the request scope it was created within. The framework provides no guarantees that a single instance of the filter will be created. Avoid using IsReusable when using a filter that depends on services with a lifetime other than singleton.
The following example demonstrates how to pass arguments to a type using TypeFilterAttribute:
[TypeFilter(typeof(AddHeaderAttribute),
Arguments = new object[] { "Author", "Steve Smith (@ardalis)" })]
public IActionResult Hi(string name)
{
return Content($"Hi {name}");
}
IFilterFactory implemented on your attribute
If you have a filter that:
- Doesn't require any arguments.
- Has constructor dependencies that need to be filled by DI.
You can use your own named attribute on classes and methods instead of [TypeFilter(typeof(FilterType))]). The following filter shows how this can be implemented:
public class SampleActionFilterAttribute : TypeFilterAttribute
{
public SampleActionFilterAttribute():base(typeof(SampleActionFilterImpl))
{
} private class SampleActionFilterImpl : IActionFilter
{
private readonly ILogger _logger;
public SampleActionFilterImpl(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
} public void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation("Business action starting...");
// perform some business logic work } public void OnActionExecuted(ActionExecutedContext context)
{
// perform some business logic work
_logger.LogInformation("Business action completed.");
}
}
}
This filter can be applied to classes or methods using the [SampleActionFilter] syntax, instead of having to use [TypeFilter] or [ServiceFilter].
Authorization filters
*Authorization filters:
- Control access to action methods.
- Are the first filters to be executed within the filter pipeline.
- Have a before method, but no after method.
You should only write a custom authorization filter if you are writing your own authorization framework. Prefer configuring your authorization policies or writing a custom authorization policy over writing a custom filter. The built-in filter implementation is just responsible for calling the authorization system.
You shouldn't throw exceptions within authorization filters, since nothing will handle the exception (exception filters won't handle them). Consider issuing a challenge when an exception occurs.
Learn more about Authorization.
Resource filters
- Implement either the IResourceFilter or IAsyncResourceFilter interface,
- Their execution wraps most of the filter pipeline.
- Only Authorization filters run before Resource filters.
Resource filters are useful to short-circuit most of the work a request is doing. For example, a caching filter can avoid the rest of the pipeline if the response is in the cache.
The short circuiting resource filter shown earlier is one example of a resource filter. Another example is DisableFormValueModelBindingAttribute:
- It prevents model binding from accessing the form data.
- It's useful for large file uploads and want to prevent the form from being read into memory.
Action filters
Action filters:
- Implement either the IActionFilter or IAsyncActionFilter interface.
- Their execution surrounds the execution of action methods.
Here's a sample action filter:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
} public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
The ActionExecutingContext provides the following properties:
- ActionArguments - lets you manipulate the inputs to the action.
- Controller - lets you manipulate the controller instance.
- Result - setting this short-circuits execution of the action method and subsequent action filters. Throwing an exception also prevents execution of the action method and subsequent filters, but is treated as a failure instead of a successful result.
The ActionExecutedContext provides Controller and Result plus the following properties:
- Canceled - will be true if the action execution was short-circuited by another filter.
- Exception - will be non-null if the action or a subsequent action filter threw an exception. Setting this property to null effectively 'handles' an exception, and Result will be executed as if it were returned from the action method normally.
For an IAsyncActionFilter, a call to the ActionExecutionDelegate:
- Executes any subsequent action filters and the action method.
- returns ActionExecutedContext.
To short-circuit, assign ActionExecutingContext.Result to some result instance and don't call the ActionExecutionDelegate.
The framework provides an abstract ActionFilterAttribute that you can subclass.
You can use an action filter to validate model state and return any errors if the state is invalid:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersSample.Filters
{
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
}
The OnActionExecuted method runs after the action method and can see and manipulate the results of the action through the ActionExecutedContext.Result property. ActionExecutedContext.Canceled will be set to true if the action execution was short-circuited by another filter.
ActionExecutedContext.Exception will be set to a non-null value if the action or a subsequent action filter threw an exception. Setting ActionExecutedContext.Exception to null:
- Effectively 'handles' an exception.
- ActionExectedContext.Result is executed as if it were returned normally from the action method.
Exception filters
Exception filters implement either the IExceptionFilter or IAsyncExceptionFilter interface. They can be used to implement common error handling policies for an app.
The following sample exception filter uses a custom developer error view to display details about exceptions that occur when the app is in development:
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IModelMetadataProvider _modelMetadataProvider; public CustomExceptionFilterAttribute(
IHostingEnvironment hostingEnvironment,
IModelMetadataProvider modelMetadataProvider)
{
_hostingEnvironment = hostingEnvironment;
_modelMetadataProvider = modelMetadataProvider;
} public override void OnException(ExceptionContext context)
{
if (!_hostingEnvironment.IsDevelopment())
{
// do nothing
return;
}
var result = new ViewResult {ViewName = "CustomError"};
result.ViewData = new ViewDataDictionary(_modelMetadataProvider,context.ModelState);
result.ViewData.Add("Exception", context.Exception);
// TODO: Pass additional detailed data via ViewData
context.Result = result;
}
}
Exception filters:
- Don't have before and after events.
- Implement OnException or OnExceptionAsync.
- Handle unhandled exceptions that occur in controller creation, model binding, action filters, or action methods.
- Do not catch exceptions that occur in Resource filters, Result filters, or MVC Result execution.
To handle an exception, set the ExceptionContext.ExceptionHandled property to true or write a response. This stops propagation of the exception. An Exception filter can't turn an exception into a "success". Only an Action filter can do that.
Note
In ASP.NET Core 1.1, the response isn't sent if you set ExceptionHandled to true and write a response. In that scenario, ASP.NET Core 1.0 does send the response, and ASP.NET Core 1.1.2 will return to the 1.0 behavior. For more information, see issue #5594 in the GitHub repository.
Exception filters:
- Are good for trapping exceptions that occur within MVC actions.
- Are not as flexible as error handling middleware.
Prefer middleware for exception handling. Use exception filters only where you need to do error handling differently based on which MVC action was chosen. For example, your 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.
The ExceptionFilterAttribute can be subclassed.
Result filters
- Implement either the IResultFilter or IAsyncResultFilter interface.
- Their execution surrounds the execution of action results.
Here's an example of a Result filter that adds an HTTP header.
public class AddHeaderFilterWithDi : IResultFilter
{
private ILogger _logger;
public AddHeaderFilterWithDi(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<AddHeaderFilterWithDi>();
} public void OnResultExecuting(ResultExecutingContext context)
{
var headerName = "OnResultExecuting";
context.HttpContext.Response.Headers.Add(
headerName, new string[] { "ResultExecutingSuccessfully" });
_logger.LogInformation($"Header added: {headerName}");
} public void OnResultExecuted(ResultExecutedContext context)
{
// Can't add to headers here because response has already begun.
}
}
The kind of result being executed depends on the action in question. An MVC action returning a view would include all razor processing as part of the ViewResult being executed. An API method might perform some serialization as part of the execution of the result. Learn more about action results
Result filters are only executed for successful results - when the action or action filters produce an action result. Result filters are not executed when exception filters handle an exception.
The OnResultExecuting method can short-circuit execution of the action result and subsequent result filters by setting ResultExecutingContext.Cancel to true. You should generally write to the response object when short-circuiting to avoid generating an empty response. Throwing an exception will:
- Prevent execution of the action result and subsequent filters.
- Be treated as a failure instead of a successful result.
When the OnResultExecuted method runs, the response has likely been sent to the client and cannot be changed further (unless an exception was thrown). ResultExecutedContext.Canceled will be set to true if the action result execution was short-circuited by another filter.
ResultExecutedContext.Exception will be set to a non-null value if the action result or a subsequent result filter threw an exception. Setting Exception to null effectively 'handles' an exception and prevents the exception from being rethrown by MVC later in the pipeline. When you're handling an exception in a result filter, you might not be able to write any data to the response. If the action result throws partway through its execution, and the headers have already been flushed to the client, there's no reliable mechanism to send a failure code.
For an IAsyncResultFilter a call to await next on the ResultExecutionDelegate executes any subsequent result filters and the action result. To short-circuit, set ResultExecutingContext.Cancel to true and don't call the ResultExectionDelegate.
The framework provides an abstract ResultFilterAttribute that you can subclass. The AddHeaderAttributeclass shown earlier is an example of a result filter attribute.
Using middleware in the filter pipeline
Resource filters work like middleware in that they surround the execution of everything that comes later in the pipeline. But filters differ from middleware in that they're part of MVC, which means that they have access to MVC context and constructs.
In ASP.NET Core 1.1, you can use middleware in the filter pipeline. You might want to do that if you have a middleware component that needs access to MVC route data, or one that should run only for certain controllers or actions.
To use middleware as a filter, create a type with a Configure method that specifies the middleware that you want to inject into the filter pipeline. Here's an example that uses the localization middleware to establish the current culture for a request:
public class LocalizationPipeline
{
public void Configure(IApplicationBuilder applicationBuilder)
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr")
}; var options = new RequestLocalizationOptions
{ DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
};
options.RequestCultureProviders = new[]
{ new RouteDataRequestCultureProvider() { Options = options } }; applicationBuilder.UseRequestLocalization(options);
}
}
You can then use the MiddlewareFilterAttribute to run the middleware for a selected controller or action or globally:
[Route("{culture}/[controller]/[action]")]
[MiddlewareFilter(typeof(LocalizationPipeline))]
public IActionResult CultureFromRouteData()
{
return Content($"CurrentCulture:{CultureInfo.CurrentCulture.Name},"
+ $"CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
}
Middleware filters run at the same stage of the filter pipeline as Resource filters, before model binding and after the rest of the pipeline.
Next actions
To experiment with filters, download, test and modify the sample.
Filters in ASP.NET Core (转自MSDN)的更多相关文章
- Filters in ASP.NET Core
Filters in ASP.NET Core allow code to be run before or after specific stages in the request processi ...
- ASP.NET Core ActionFilter引发的一个EF异常
最近在使用ASP.NET Core的时候出现了一个奇怪的问题.在一个Controller上使用了一个ActionFilter之后经常出现EF报错. InvalidOperationException: ...
- ASP.NET Core 2 学习笔记(十四)Filters
Filter是延续ASP.NET MVC的产物,同样保留了五种的Filter,分别是Authorization Filter.Resource Filter.Action Filter.Excepti ...
- [转]ASP.NET Core Exception Filters and Resource Filters
本文转自:https://damienbod.com/2015/09/30/asp-net-5-exception-filters-and-resource-filters/ This article ...
- Asp.Net Core 进阶(四)—— 过滤器 Filters
一.介绍 Asp.Net Core Filter 使得可以在请求处理管道的特定阶段的前后执行代码,我们可以创建自定义的 filter 用于处理横切关注点. 横切关注点的示例包括错误处理.缓存.配置.授 ...
- 理解ASP.NET Core - 过滤器(Filters)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 Filter概览 如果你是从ASP.NET一路走过来的,那么你一定对过滤器(Filter)不陌 ...
- ASP.NET Core 中的 WebSocket 支持(转自MSDN)
本文介绍 ASP.NET Core 中 WebSocket 的入门方法. WebSocket (RFC 6455) 是一个协议,支持通过 TCP 连接建立持久的双向信道. 它用于从快速实时通信中获益的 ...
- Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例
本文目录 1. Net下日志记录 2. NLog的使用 2.1 添加nuget引用NLog.Web.AspNetCore 2.2 配置文件设置 2.3 依赖配置及调用 ...
- 从ASP.NET到ASP.NET Core差异变化
MSDN原文:链接 ASP.NET Core项目为开发人员提供了针对.NET Core,.NET Framework2种实现方式,根据官网通告NETCORE3.0后将取消对.NET Framework ...
随机推荐
- 1142 奖学金 sort做法
个人博客:doubleq.win 1142 奖学金 2007年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题解 题目 ...
- Django请求生命周期之响应内容
Django请求生命周期: 1.发送http请求2.服务器接受,根据请求头中的url在路由关系表中进行匹配(从上到下)3.匹配成功后,执行指定的views函数 URL -> 函数 ==>F ...
- toast, 警告窗
//浮动提示框 1秒后消失 toast(msg, isError, sec) { var div = $('#toast'); div.html(msg); div.css({visibility: ...
- Vuejs入门级简单实例
Vue作为2016年最火的框架之一,以其轻量.易学等特点深受大家的喜爱.今天简单介绍一下Vue的使用. 首先,需要在官网下载vuejs,或者直接用cdn库.以下实例使用Vue实现数据绑定与判断循环: ...
- VC++中如何将字符串转换成整型数字
原文:http://blog.csdn.net/yongf2014/article/details/47071663 注意: atoi函数是c的函数,它的输入参数是char *类型. 你声明了stri ...
- weex 数据绑定,动态控制组件的显示内容及样式
无论的原生开发还是weex开发,经常会需要我们对一些组件/控件动态赋值,在原生中,我们大家都知道,对控件setText就可以了,那么在weex中呢,我们需要怎么做呢,其实很简单,几行代码就可以搞定!首 ...
- Python3 中日语料分句实现
0. 背景 因为最近在看平行语料句对齐.词对齐的缘故,想做对齐的话需要先做一个分句. 一开始利用正则和引号开关标志写了一种方法,中间想到一个小技巧,写出来比较简单通用,想把这一小段代码分享一下. 1. ...
- 毕向东_Java基础视频教程第19天_IO流(20~22)
第19天-20-IO流(改变标准输入输出设备) static void setIn(InputStream in) Reassigns the "standard" input s ...
- CSS盒子模型中()是透明的,这部分可以显示背景()
CSS盒子模型中()是透明的,这部分可以显示背景() border margin padding content 我的理解: · Margin(外边距) - 清除边框外的区域,外边距是透明 ...
- asp.net 服务器控件的 ID,ClientID,UniqueID 的区别
1.简述 ID是设计的时候自己所指定的ID,是我们分配给服务器控件的编程标识符,我们常常使用this.controlid来寻找控件,那么这个controlid就是这里所说的ID. ClientID是由 ...