Search code examples
c#asp.net-core.net-6.0razor-pages

ASP.NET Core: How to inject ApplicationDbContext in IPageFilter


ASP.NET Core 6: I am trying to create an IPageFilter for Razor pages, this filter will need to use the ApplicationDbContext that is registered in the DI container in Program.cs.

In my filter, I am injecting the ApplicationDbContext in the constructor, but when I decorate a Razor page with it, it shows an error that I am not injecting the context. What's the correct way to do this?

The filter:

[AttributeUsage(AttributeTargets.Class)]
public class CustomPageFilterAttribute : Attribute, IAsyncPageFilter 
{
    protected ApplicationDbContext _db;

    public CustomPageFilterAttribute(ApplicationDbContext db) 
    {
        _db = db;
    }

    public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) 
    {
        var something = _db.Customers.Find(1);
        return Task.CompletedTask;
    }

    // Executes last
    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) 
    {
        // Before action execution
        await next();
        // After action execution
    }
}

The Razor page:

[CustomPageFilterAttribute]
public class ConfigUsuarioModel : PageModel
{
    private readonly ApplicationDbContext _db;

    [BindProperty]
    public ConfigUsuario _configUsuario { get; set; }

    [TempData]
    public string StatusMessage { get; set; }

    //ctor
    public ConfigUsuarioModel(ApplicationDbContext db) 
    {
        _db = db;
    }
}

Register DbContext in Program.cs of MVC project:

builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString, sqlServerOptions => sqlServerOptions.CommandTimeout(90)));

Intellisense marks an error in decorating the PageModel with [CustomPageFilterAttribute]:

There is no argument given that corresponds to the required parameter 'db' of 'CustomPageFilterAttribute.CustomePageFilterAttribute(ApplicationDbContext)'


Solution

  • The compilation error mentions that you are not providing the parameter to CustomPageFilterAttribute and there is no empty constructor in your CustomPageFilterAttribute.

    In your scenario, you are trying to get the ApplicationDbContext from the DI container, thus you have to implement via ServiceFilterAttribute.

    using Microsoft.AspNetCore.Mvc;
    
    [ServiceFilter(typeof(CustomPageFilterAttribute))]
    public class ConfigUsuarioModel : PageModel
    {
        ...
    }
    

    Make sure you are registering the CustomPageFilterAttribute in the Program.cs.

    builder.Services.AddScoped<CustomPageFilterAttribute>();
    

    enter image description here