下面是“.NET 6开发TodoList应用之实现ActionFilter”的完整攻略。
前言
在Web应用的开发中,ActionFilter 可以帮助我们在请求流程中执行一些共享的逻辑,例如,身份验证、日志记录、全局异常处理等等。使用ActionFilter 可以将这些逻辑隔离到一个独立的类中,使得各个控制器方法之间耦合度更低,代码复用更高效。
在后续的示例中,我们将演示如何通过实现一个ActionFilter来给TodoList增加一个“TRACE”功能。
实现步骤
创建ActionFilter类
在项目中创建一个新的类文件,例如,我们可以创建一个名为TraceActionFilter.cs
的类,这个类继承自IActionFilter
。下面是示例代码:
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
namespace TodoListWebApp.ActionFilters
{
public class TraceActionFilter : IActionFilter
{
private readonly ILogger<TraceActionFilter> logger;
public TraceActionFilter(ILogger<TraceActionFilter> logger)
{
this.logger = logger;
}
public void OnActionExecuting(ActionExecutingContext context)
{
logger.LogInformation($"Action {context.ActionDescriptor.DisplayName} start executing");
context.HttpContext.Items.Add("Stopwatch", Stopwatch.StartNew());
}
public void OnActionExecuted(ActionExecutedContext context)
{
var stopwatch = (Stopwatch)context.HttpContext.Items["Stopwatch"];
stopwatch.Stop();
logger.LogInformation($"Action {context.ActionDescriptor.DisplayName} finished executing in {stopwatch.ElapsedMilliseconds}ms");
}
}
}
代码解释:
- 首先,我们在构造函数中注入了一个ILogger实例,用于日志的记录;
- 在OnActionExecuting方法中,我们使用ILogger记录Action方法开始执行;
- 我们使用HttpContext.Items字典存储一个StopWatch,
- 然后在OnActionExecuted方法中,我们获取StopWatch并停止计时,
- 然后记录Action方法执行的时间。
注册ActionFilter
我们需要将此ActionFilter注册到Startup.cs中。其中使用services.AddScoped<>()
方法,将其添加到DI容器中:
services.AddScoped<TraceActionFilter>();
然后我们在Configure方法中,使用MapControllerRoute方法让全局应用该ActionFilter:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" })
.RequireAuthorization()
.WithMetadata(new TraceActionFilter());
});
在示例中,我们需要全局对TodoList应用启用ActionFilter,因此我们给MapControllerRoute方法添加了WithMetadata方法,该方法会应用指定的ActionFilter。
应用ActionFilter
在需要应用ActionFilter的Controller或method上增加特性,例如在TodoListsController的GetAll方法上应用我们实现的TraceActionFilter就可以了:
[HttpGet]
[TraceActionFilter]
public async Task<ActionResult<IEnumerable<TodoItem>>> GetAll()
{
var todoItems = await todoItemService.GetTodoItemsAsync();
return Ok(todoItems);
}
运行应用
现在我们可以使用Postman或Fiddler等工具来模拟HTTP请求访问我们的TodoList应用。当我们访问GetAll方法时,我们就可以在应用的日志中看到类似以下的输出:
info: TodoListWebApp.ActionFilters.TraceActionFilter[0]
Action TodoListsController.GetAll start executing
info: TodoListWebApp.ActionFilters.TraceActionFilter[0]
Action TodoListsController.GetAll finished executing in 60ms
在以上输出中,我们可以看到我们的TraceActionFilter输出了Action方法开始执行和完成执行的日志,并且在完成执行时,输出了Action执行的时间。
示例说明
在实现ActionFilter意味着我们可以很方便地执行各种共享的逻辑。例如,我们在上述示例中实现的TraceActionFilter可以方便地增加跟踪Action执行时间的功能;我们也可以实现身份验证逻辑,添加数据缓存,全局异常处理等等。ActionFilter可以帮助我们使控制器代码保持最佳实践,同时也方便了代码复用和维护。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET 6开发TodoList应用之实现ActionFilter - Python技术站