在 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
。
我需要记录某些用户操作,例如登录、注销、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
。