HttpContextAccessor.HttpContext在Linux上为null,而在ServiceStack.Core

时间:2017-11-08 21:53:18

标签: ubuntu asp.net-core .net-core servicestack httpcontext

我有一个在.NET Core 2.0上运行的简单ServiceStack项目。这在Windows上工作正常但在Linux上失败。使用相同的代码(见下文)。

服务注入IHttpContextAccessor,它始终为非空(Win& Linux),但其属性HttpContext在Linux上始终为null,在Windows上始终为非null。

重现问题的最小项目:

using Funq;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using ServiceStack;

namespace TestSS
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services) { }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseDeveloperExceptionPage();
            app.UseServiceStack(new AppHost());
        }
    }

    public class AppHost : AppHostBase
    {
        public AppHost() : base("AO", typeof(InfoService).Assembly) { }

        public override void Configure(Container container)
        {
            var httpContextAccessor = new HttpContextAccessor();
            container.Register<IHttpContextAccessor>(httpContextAccessor);
        }
    }

    public class InfoService : Service
    {
        [Route("/info")] public class InfoRequest { }

        private readonly IHttpContextAccessor _accessor;

        public InfoService(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }

        public object Any(InfoRequest request)
        {
            return $"Accessor: {_accessor};\nContext: {_accessor.HttpContext};";
        }
    }
}

关于如何在Linux上运行项目:没有反向代理(nginx等),只有dotnet build后跟dotnet run,在本地访问。没有什么花哨的,没有什么令人费解的恕我直言。

Win:Windows 10企业版

Linux:Ubuntu 16.04 LTS

dotnet --version:2.0.2(两个平台)

进一步调查:

在AppHost.Configure方法中注释IHttpContextAccessor注册有一个奇怪的效果:在Windows上没有任何变化,一切都按预期工作,在Linux上抛出异常,因为无法实现依赖。

有没有人有解决方案,解决方法,任何信息?

1 个答案:

答案 0 :(得分:4)

这对我来说很奇怪,但似乎解决方法是注册IHttpContextAccessor。这并不意味着它绝对是问题的核心,但至少我让事情有效。

在两个平台上,完全相同的代码(直到最后一个字符)表现不同,这当然是一个问题。

所以解决方法是删除AppHost.Configure中的两行:

var httpContextAccessor = new HttpContextAccessor();
container.Register<IHttpContextAccessor>(httpContextAccessor);

并在IHttpContextAccessor方法中注册Startup.ConfigureServices

services.AddSingleton<IHttpContextAccessor>(new HttpContextAccessor());

...这解决了我的问题。

如果您需要像我一样拥有HttpContextAccessor方法中AppHost.Configure的实例,您可以在Startup.Configure方法中检索实例并通过构造函数将其注入AppHost实例。检索完成如下:

var httpContextAccessor = (IHttpContextAccessor)app.ApplicationServices.GetService(typeof(IHttpContextAccessor));

总而言之,这很奇怪,因为我可以在Windows上注册而不是在Linux上注册,因此必定存在某种错误。