question

Tracy-8071 avatar image
0 Votes"
Tracy-8071 asked Bruce-SqlWork answered

Static Visit HttpContext under Net5.0

Recently I tried to upgrade one web project from .net core 2.2 to .net 5.0, but I run it with System.NullReferenceException of HttpContext.
138043-httpcontext-nullreferenceexception-2021-10-05-1657.png
And I have searched for long time without fixing it. Please kindly give your kind help. Many thanks!
The main code is as bellow:
1)HttpContextCore.cs:
public class HttpContextCore
{
public static HttpContext Current { get => AutofacHelper.GetService<IHttpContextAccessor>().HttpContext; }
}
2)Program.cs:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

     /// <summary>
     /// changed from IWebHostBuilder to IHostBuilder for .net5.0 upgrade in 2021-09-25
     /// </summary>
     /// <param name="args"></param>
     /// <returns></returns>
     public static IHostBuilder CreateHostBuilder(string[] args) =>
         Host.CreateDefaultBuilder(args)
             //Autofac for .net5.0 upgrade in 2021-09-25
             .UseServiceProviderFactory(new AutofacServiceProviderFactory())
             .ConfigureWebHostDefaults(webBuilder =>
             {
                 webBuilder.UseStartup<Startup>();
             });
 }

3)Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

     public IConfiguration Configuration { get; }

     //autofac for .net5.0 upgrade
     public ILifetimeScope AutofacContainer { get; private set; }

     // This method gets called by the runtime. Use this method to add services to the container.
     public void ConfigureServices(IServiceCollection services)
     {
         services.AddDbContext<APPContext>(options =>
         {
             var connectionString = this.Configuration["ConnectionStrings:App"];  
             options.UseSqlServer(connectionString);
         });
         //Session
         services.AddSession(options =>
         {
             options.IdleTimeout = TimeSpan.FromMinutes(240);
             options.Cookie.HttpOnly = true;
         });

         #region upgrade net5.0 
         services.AddControllersWithViews(options =>
         {
             options.Filters.Add<CheckLoginFilters>();
             options.Filters.Add<CheckPermissionFilters>();
         })
         .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
         .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
         #endregion

         services.AddScoped<IHttpContextAccessor, HttpContextAccessor>(); 
     }

     /// <summary>
     /// ConfigureContainer is where you can register things directly with Autofac that run after ConfigureServices.
     /// </summary>
     /// <param name="builder"></param>
     public void ConfigureContainer(ContainerBuilder builder)
     {
         builder.RegisterModule(new DefaultModule());
     }

     /// <summary>
     /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     /// </summary>
     /// <param name="app"></param>
     /// <param name="env"></param>
     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
         app.UseDeveloperExceptionPage();

         //autofac 
         this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();

         app.UseStaticFiles();
         app.UseCookiePolicy();
         app.UseSession();
         app.UseRouting();
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllerRoute(
                 name: "areas",
                 pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
             endpoints.MapControllerRoute(
                 name: "default",
                 pattern: "{controller=Home}/{action=Index}/{id?}");
         });
         #endregion
     }
 }


dotnet-csharpdotnet-aspnet-core-general
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I have to add that it works under .net core2.2. Thanks!

0 Votes 0 ·

1 Answer

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

This approach was always a hack. HttpContextAdapter uses thread Async Local storage to store the context. This means the caller must be on the same async call chain as a pipeline async call that sets the context.

You should refactor you code to not use a static accessor for HttpContext.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.