C
C#Senpawaii

❔ Accessing HTTP Context at DbCommandInterceptor [.NET 7]

Hi! I'm having some issues trying to access the HTTP Context at my DbCommand Interceptor class. What I'm trying to achieve is similar to the one presented in: https://stackoverflow.com/questions/75033870/getting-httpcontext-or-just-user-information-into-dbconnectioninterceptor-in I have tried following advices as present in https://weblogs.asp.net/ricardoperes/accessing-the-httpcontext-from-a-dbcontext , however, when I try to access the HttpContext from the IHttpContextAccessor, I always get a Null object. Ultimately, what I want to do is inject the IHttpContextAccessor class through the DbContext class’ constructor, so that I can provide it to the Interceptor. Can someone lend me some much appreciated advice on how to solve this? This is the implementation of my Interceptor.
public class DemoInterceptor : DbCommandInterceptor {
private readonly IHttpContextAccessor _contextAccessor;
public DemoInterceptor(IHttpContextAccessor contextAccessor) {
_contextAccessor = contextAccessor;
}

[omitted sync override]

public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result,
CancellationToken cancellationToken = default) {

ModifyCommand(command);

return new ValueTask<InterceptionResult<DbDataReader>>(result);
}

private void ModifyCommand(DbCommand command) {
Console.WriteLine(_contextAccessor.HttpContext.Request.Path);
}
}
public class DemoInterceptor : DbCommandInterceptor {
private readonly IHttpContextAccessor _contextAccessor;
public DemoInterceptor(IHttpContextAccessor contextAccessor) {
_contextAccessor = contextAccessor;
}

[omitted sync override]

public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result,
CancellationToken cancellationToken = default) {

ModifyCommand(command);

return new ValueTask<InterceptionResult<DbDataReader>>(result);
}

private void ModifyCommand(DbCommand command) {
Console.WriteLine(_contextAccessor.HttpContext.Request.Path);
}
}
Stack Overflow
Getting HttpContext (or just user information) into DbConnectionInt...
I am trying to setup RLS by running sp_set_session_context at the point of connection to my SQL Server database via a DbConnectionInterceptor. It works fabulously when I use a hardcoded Username, ...
S
Senpawaii398d ago
The implementation of the custom DbContext class, where the Interceptor is added:
public class CatalogContext : DbContext
{
public CatalogContext(DbContextOptions<CatalogContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
{
_httpContextAccessor = httpContextAccessor;
}
private readonly IHttpContextAccessor _httpContextAccessor;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.AddInterceptors(new DemoInterceptor(_httpContextAccessor));
}
}
public class CatalogContext : DbContext
{
public CatalogContext(DbContextOptions<CatalogContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
{
_httpContextAccessor = httpContextAccessor;
}
private readonly IHttpContextAccessor _httpContextAccessor;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.AddInterceptors(new DemoInterceptor(_httpContextAccessor));
}
}
How I configure my Services and dependencies (using Autofac):
public Startup(IConfiguration configuration) {
Configuration = configuration;
}

public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor()
.AddCustomDbContext(Configuration)
[ ... ]

var container = new ContainerBuilder();
container.Populate(services);

return new AutofacServiceProvider(container.Build());
}
public Startup(IConfiguration configuration) {
Configuration = configuration;
}

public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor()
.AddCustomDbContext(Configuration)
[ ... ]

var container = new ContainerBuilder();
container.Populate(services);

return new AutofacServiceProvider(container.Build());
}
And finally the implementation of AddCustomDbContext, called on the previous code block.
public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
{
services.AddEntityFrameworkSqlServer()
.AddDbContext<CatalogContext>(options => {
options.UseSqlServer( ... );
});

});
return services;
}
public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
{
services.AddEntityFrameworkSqlServer()
.AddDbContext<CatalogContext>(options => {
options.UseSqlServer( ... );
});

});
return services;
}
A
Accord397d ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.