51

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?

Community
  • 1
  • 1
Kolya_Net
  • 1,050
  • 3
  • 13
  • 25
  • 5
    If you look at the breaking changes for .Net Core, you can see that `IHttpContextAccessor` is no longer registered by default. https://github.com/aspnet/Hosting/issues/793 – DavidG Jul 04 '16 at 12:23

4 Answers4

118

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

Kit
  • 20,354
  • 4
  • 60
  • 103
Oleksandr Fentsyk
  • 5,256
  • 5
  • 34
  • 41
  • 4
    Official announcement: https://github.com/aspnet/Announcements/issues/190 – MartinHN Jul 04 '16 at 14:56
  • 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.cs` – Kolya_Net Jul 05 '16 at 08:26
  • 8
    one question shouldn't this be `AddTransient` because its will be for a request? – Ruchan Jul 06 '16 at 09:13
  • 2
    @Ruchan Did you ever get an answer for this? Should it be singleton or transient? – Reft May 14 '17 at 16:53
  • 5
    @Reft I used Singleton. here is more info on this https://github.com/aspnet/Hosting/issues/793 read the answer by davidfowl – Ruchan May 15 '17 at 07:00
  • I am wondering why this is injected as singleton, rather than as scoped (per-request). – MovGP0 Mar 21 '18 at 17:31
  • @Ruchan 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. – MovGP0 Mar 21 '18 at 17:35
  • `.AddIdentity()` is already providing the registration https://github.com/aspnet/Hosting/issues/793#issuecomment-224831136 – SerjG Sep 24 '18 at 19:23
  • 2
    @Ruchan Registering the `IHttpContextAccessor` as singleton works because it uses `AsyncLocal` to store the HttpContext. – Memet Olsen Aug 21 '19 at 09:39
  • 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: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-6.0#use-httpcontext-from-grpc-methods – GameSalutes Jun 07 '22 at 15:27
11

You can add in this way for .Net 6

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
amurra
  • 15,221
  • 4
  • 70
  • 87
Muammer
  • 374
  • 2
  • 11
2

You can add in this way.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Pang
  • 9,564
  • 146
  • 81
  • 122
Samif
  • 57
  • 8
0

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

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor
  • 2
    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](/help/how-to-answer). – Community Jan 11 '23 at 21:42