在 ASP.NET Core MVC 中将它用于 ActionFilter 时出现 DbContext 错误

DbContext error when using it for ActionFilter in ASP.NET Core MVC

我需要记录某些用户操作,例如登录、注销、CRUD 等,并保存到名为 AuditRecords 的 table。我有一个 DbContext 叫做 AuditContext:

我了解到应用 ActionFilter 并用它装饰控制器方法是可行的方法。 AuditContext 导致红色波浪形要求 'options',这让我感到困惑。我试过 DI,但得到了相同的结果。有什么想法吗?我在 DotNet 5.01 上,但我也用 DotNet 6 尝试过,结果相同。

编辑 我更改了 AuditAttribute 和 Context 以使其尽可能简单,并按照建议使用依赖注入。但是问题还是没有解决

 public class Audit
{
    //Audit Properties
    public Guid AuditID { get; set; }
    public string UserName { get; set; }
    public string IPAddress { get; set; }
    public string AreaAccessed { get; set; }
    public DateTime Timestamp { get; set; }

    //Default Constructor
    public Audit() { }
}

public class AuditContext : DbContext
{
    public DbSet<Audit> AuditRecords { get; set; }
}
public class HomeController : Controller
{
   //red squiggly under [Audit] decoration with error of no formal
   //parameter 'context' in AuditAttribute.AuditAttribute(AuditContext)
    [Audit]  
    public IActionResult Privacy()
    {
        return View();
    }

//AuditAttribute class
using Microsoft.AspNetCore.Mvc.Filters;
using System;

namespace LoggingDemoMVC.Filters
{
public class AuditAttribute : ActionFilterAttribute
{
    private readonly AuditContext _context;

    public AuditAttribute(AuditContext context)
    { 
        _context = context;
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //Stores the Request in an Accessible object
        var request = filterContext.HttpContext.Request;
        //Generate an audit
        Audit audit = new Audit()
        {
            //Your Audit Identifier     
            AuditID = Guid.NewGuid(),
            //Our Username (if available)
            UserName = (filterContext.HttpContext.User.Identity.IsAuthenticated) ? filterContext.HttpContext.User.Identity.Name : "Anonymous",
            //The IP Address of the Request
            IPAddress = request.Path,
            //The URL that was accessed
            AreaAccessed = request.HttpContext.Request.Path,
            //Creates our Timestamp
            Timestamp = DateTime.UtcNow
        };

        //Stores the Audit in the Database
        
        _context.AuditRecords.Add(audit);
        _context.SaveChanges();

        //Finishes executing the Action as normal 

        base.OnActionExecuting(filterContext);
    }
}

}

WebAppContext 期望将 DbContext<WebAppContext> 传递到其构造函数中。但是,您在调用构造函数时未提供任何内容:

WebAppContext _context = new WebAppContext()

要解决此问题,您只需插入已设置的依赖注入系统

public class CustomFilter : IActionFilter
    {
        private readonly WebAppContext _context;
        public CustomFilter(WebAppContext context)
        {
            _context = context;
        }
      
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //.......
                
            _context.AuditRecords.Add(...);
            _context.SaveChanges();
        }
    }

简单演示:

型号

public class Audit
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

DataContext

 public class WebAppContext : DbContext
    {
        public WebAppContext(DbContextOptions<WebAppContext> options) : base(options)
        {

        }
        public DbSet<Audit> AuditRecords { get; set; }
    }

自定义过滤器

public class CustomFilter :Attribute,IActionFilter
    {
        private readonly WebAppContext _context;
        public CustomFilter(WebAppContext context)

        {
            _context = context;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            Console.WriteLine("end");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            Audit audit = new Audit();
           
            audit.Name = "mike";
                
            _context.AuditRecords.Add(audit);
            _context.SaveChanges();
        }
    }

启动

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            //config database
            services.AddDbContext<WebAppContext>(option=>option.UseSqlServer(Configuration.GetConnectionString("default")));
            //add filter
            services.AddScoped<CustomFilter>();
        }

控制器

[TypeFilter(typeof(CustomFilter))]
public IActionResult Privacy()
{
    return View();
}

当我访问Privacy方法时,数据库会添加一行数据

首先,将 Nuget 包 Microsoft.EntityFrameworkCore.SqlServer 添加到您的项目中。 然后,将以下代码添加到 Startup class 的 ConfigureServices 方法中:

services.AddDbContext<WebAppContext>(options =>
 options.UseSqlServer("[your connectionstring here]"));

这是最低要求,这将使您能够将 DbContext 注入 ActionFilter