Blazor Server IHttpContextAccessor returning null when deployed

Richard Baker 21 Reputation points
2023-01-09T17:22:52.197+00:00

I am dynamically setting the connection string based on the user that is logged in. This is working perfectly when running locally/debugging but when its deployed it's returning a null reference exception. This is my DbContext and I am handling the connection string logic in the OnConfigure method:

namespace SwordfishCRM.Services.ApplicationDbContext  
{  
    public class PrimaryApplicationDbContext : IdentityDbContext<ApplicationUser>  
    {  
        private readonly HttpContext context;  
        private readonly IConfiguration configuration;  
  
        public PrimaryApplicationDbContext(DbContextOptions<PrimaryApplicationDbContext> options, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) : base(options)  
        {  
            this.context = httpContextAccessor.HttpContext;  
            this.configuration = configuration;  
        }  
  
        //Tables  
        public DbSet<Address> Addresses { get; set; }  
        public DbSet<ChimneySweepCycle> ChimneySweepCycles { get; set; }  
        public DbSet<ChimneySweepMethod> ChimneySweepMethods { get; set; }  
        public DbSet<ContactMethod> ContactMethods { get; set; }  
        public DbSet<ContactPreference> ContactPreferences { get; set; }  
        public DbSet<Customer> Customers { get; set; }  
        public DbSet<Diary> Diary { get; set; }  
        public DbSet<DiaryDate> DiaryDates { get; set; }  
        public DbSet<DiaryOption> DiaryOptions { get; set; }  
        public DbSet<Gender> Genders { get; set; }  
        public DbSet<Job> Jobs { get; set; }  
        public DbSet<JobActualLine> JobActualLines { get; set; }  
        public DbSet<JobApproval> JobApprovals { get; set; }  
        public DbSet<JobQuoteLine> JobQuoteLines { get; set; }  
        public DbSet<JobStatus> JobStatuses { get; set; }  
        public DbSet<JobType> JobTypes { get; set; }  
        public DbSet<Product> Products { get; set; }  
        public DbSet<Report> Reports { get; set; }  
        public DbSet<RetroSweepingCertificate> RetroSweepingCertificates { get; set; }  
        public DbSet<ScheduleDay> ScheduleDays { get; set; }  
        public DbSet<ScheduleExceptionDay> ScheduleExceptionDays { get; set; }  
        public DbSet<Title> Titles { get; set; }  
  
        //Views  
        public virtual DbSet<vwAvailableApoointment> vwAvailableApoointments { get; set; }  
  
        protected override void OnModelCreating(ModelBuilder modelBuilder)  
        {  
            base.OnModelCreating(modelBuilder);  
  
            modelBuilder  
                .Entity<vwAvailableApoointment>(eb =>  
                {  
                    eb.HasNoKey();  
                    eb.ToView("vwAvailableApoointments");  
                });  
        }  
  
  
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  
        {  
            var userId = context.User.Identity.Name;  
            if (userId == null)  
            {  
                optionsBuilder.UseSqlServer(configuration.GetConnectionString("Master"));  
            }  
            else  
            {  
                var prefix = IdentitySupport.GetConnectionPrefix(userId);  
                optionsBuilder.UseSqlServer(configuration.GetConnectionString(prefix));  
            }          
        }  
    }  
}  

This is the console error when it's been deployed:

Error: System.NullReferenceException: Object reference not set to an instance of an object.  
   at SwordfishCRM.Services.ApplicationDbContext.PrimaryApplicationDbContext.OnConfiguring(DbContextOptionsBuilder optionsBuilder) in D:\a\1\s\SwordfishCRM.Services\ApplicationDbContext\PrimaryApplicationDbContext .cs:line 67  
   at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()  
   at Microsoft.EntityFrameworkCore.DbContext.get_Model()  
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()  
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()  
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()  
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()  
   at System.Linq.Queryable.OrderBy[TSource,TKey](IQueryable`1 source, Expression`1 keySelector)  
   at SwordfishCRM.Web.Pages.Swordfish.DiaryScheduleExceptionDates.OnInitializedAsync() in D:\a\1\s\SwordfishCRM.Web\Pages\Swordfish\DiaryScheduleExceptionDates.razor:line 25  
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()  

I am confused why this run's locally but not when deployed. I would welcome any support. Thank you

I have tried different variations of HTTPContext but to no avail. I am expecting it to find the logged in user, so I can retrieve a code to set the connection string. There is a fail safe to use the config for the Master database (this is not the actual Master database, just a name for the main database with all the users etc...) There is a step before this that if they are not logged in, they wont even hit this screen.

Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
694 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,372 questions
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 54,621 Reputation points
    2023-01-09T20:48:36.343+00:00

    you should inject the AuthenticationStateProvider instead of context.


0 additional answers

Sort by: Most helpful