How to add IHttpContextAccessor in the Startup class in the DI in ASP.NET Core 1.0?
Asked Answered
A

4

58

In ASP.NET Core RC 1 I used the following code to retrieve the value of context (full address of the page). Then I recorded this value in the configuration.

public class Startup
{
        public IConfigurationRoot Configuration { get; set; }
        private IHostingEnvironment CurrentEnvironment { get; set; }
        private IHttpContextAccessor HttpContextAccessor { get; set; }
        public Startup(IHostingEnvironment env,
                IHttpContextAccessor httpContextAccessor)
            {                
                var builder = new ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
    
                if (env.IsDevelopment())
                {
                    builder.AddUserSecrets();
                }
                builder.AddEnvironmentVariables();
                Configuration = builder.Build();
                CurrentEnvironment = env;
                HttpContextAccessor = httpContextAccessor;
            }
        public void ConfigureServices(IServiceCollection services)
        {
        ...
        
        services.AddOptions();
        services.Configure<WebAppSettings>(configuration);
        services.Configure<WebAppSettings>(settings =>
        {
            ...
            settings.WebRootPath = CurrentEnvironment.WebRootPath;
            settings.DomainUrl = HttpContextAccessor.HttpContext.Request.Host.ToUriComponent();
        });
        }
   }

Now I started to update the project on ASP.NET Core 1.0. But during the launch of the site I get the following error:

System.InvalidOperationException Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' while attempting to activate 'MyProject.Startup'.

at Microsoft.Extensions.Internal.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.Extensions.Internal.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type) at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider services, Type startupType, string environmentName) at Microsoft.AspNetCore.Hosting.<>c__DisplayClass1_0.b__1(IServiceProvider sp) at Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryService.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ScopedCallSite.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.SingletonCallSite.Invoke(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.<>c__DisplayClass12_0.b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider) at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup() at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

.NET Framework X64 v4.0.30319.42000 | Microsoft.AspNetCore.Hosting version 1.0.0-rtm-21431 | Microsoft Windows 6.1.7601 S

How do I get the new version IHttpContextAccessor during application startup?

Artillery answered 4/7, 2016 at 12:16 Comment(1)
If you look at the breaking changes for .Net Core, you can see that IHttpContextAccessor is no longer registered by default. github.com/aspnet/Hosting/issues/793Ilke
S
123

It is no longer a default service. You have to configure it in Startup.cs

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

UPDATE: In ASP.NET Core 2.1, the AddHttpContextAccessor helper extension method was added to correctly register the IHttpContextAccessor with the correct lifetime (singleton). So, in ASP.NET Core 2.1 and above, the code should be

services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

Source: https://github.com/aspnet/Hosting/issues/793

Symptom answered 4/7, 2016 at 13:33 Comment(10)
Official announcement: github.com/aspnet/Announcements/issues/190Whoreson
Adding dependencies Startap.cs does not solve my problem because IHttpContextAccessor must be used in the class constructor. So I added a dependency in the Program.csArtillery
one question shouldn't this be AddTransient because its will be for a request?Third
@Third Did you ever get an answer for this? Should it be singleton or transient?Margravine
@Margravine I used Singleton. here is more info on this github.com/aspnet/Hosting/issues/793 read the answer by davidfowlThird
I am wondering why this is injected as singleton, rather than as scoped (per-request).Loidaloin
@Third no. AddTransient would create a new instance for every service, but the HttpContext is just injected into the HttpContextAccessor once. Every other required HttpContextAccessor would not have the HttpContext.Loidaloin
.AddIdentity() is already providing the registration github.com/aspnet/Hosting/issues/793#issuecomment-224831136Peroxide
@Third Registering the IHttpContextAccessor as singleton works because it uses AsyncLocal<T> to store the HttpContext.Touchhole
If you are using Dotnet 6, this is a link to the official Microsoft documentation on the topic. Hasn't changed from this answer's recommendation: learn.microsoft.com/en-us/aspnet/core/fundamentals/…Bloom
P
13

You can add in this way for .Net 6

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Pearly answered 22/2, 2022 at 8:8 Comment(0)
L
4

You can add in this way.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Leroy answered 8/10, 2020 at 8:51 Comment(1)
Correct answer. You'd typically want to add that into ConfigureServices().Assimilative
S
0

.NET 6, without the full path gives an error, worked for me:

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor
Senghor answered 11/1, 2023 at 16:44 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Swithbert

© 2022 - 2024 — McMap. All rights reserved.