【问题标题】:Trying to configure multiple .NET Core pipelines, HttpContext ends up null尝试配置多个 .NET Core 管道,HttpContext 最终为 null
【发布时间】:2019-05-31 08:41:21
【问题描述】:

我正在尝试按照本指南在我的 MVC 应用程序中创建 API 部分和 MVC 部分之间的逻辑分隔:

https://www.strathweb.com/2017/04/running-multiple-independent-asp-net-core-pipelines-side-by-side-in-the-same-application/

这是我对他正在使用的扩展方法的实现:

    public static IApplicationBuilder UseBranchWithServices(this IApplicationBuilder app,
        PathString path, Action<IServiceCollection> servicesConfiguration,
        Action<IApplicationBuilder> appBuilderConfiguration)
    {
        var webhost = new WebHostBuilder()
            .UseKestrel()
            .ConfigureServices(servicesConfiguration)
            .UseStartup<StartupHarness>()
            .Build()
  /* ojO */ .CreateOrMigrateDatabase(); /* Ojo */

        var serviceProvider = webhost.Services;
        var featureCollection = webhost.ServerFeatures;
        var appFactory = serviceProvider.GetRequiredService<IApplicationBuilderFactory>();
        var branchBuilder = appFactory.CreateBuilder(featureCollection);
        var factory = serviceProvider.GetRequiredService<IServiceScopeFactory>();

        branchBuilder.Use(async (context, next) => {
            using (var scope = factory.CreateScope()) {
                context.RequestServices = scope.ServiceProvider;
                await next();
            }
        });

        appBuilderConfiguration(branchBuilder);

        var branchDelegate = branchBuilder.Build();

        return app.Map(path, builder => { builder.Use(async (context, next) => {
            await branchDelegate(context);
          });
        });
    }

当我尝试将它和 SignInManager 一起使用时,HttpContext 始终为空。

这是我的 AccountController 的一个可笑的简化版本:

    public AccountController(SignInManager<AppUser> mgr) {
        _mgr = mgr;
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var result = await _mgr.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, lockoutOnFailure: false);
        }
    }

我是 ApplicationBuilder 中的calling app.UseAuthentication();为简洁起见,我将该设置作为扩展方法。这有效:

    public void ConfigureServices(IServiceCollection services)
    {
        services.ConfigureMvcServices(Configuration);
    }

    public void Configure(IApplicationBuilder builder, IHostingEnvironment env)
    {
        builder.ConfigureMvcBuilder(env);
    }

这不是:

    public void Configure(IApplicationBuilder builder, IHostingEnvironment env)
    {
        builder.UseBranchWithServices(StaticConfiguration.RootPath,
            services =>
            {
                services.ConfigureMvcServices(Configuration); 
            },
            app => { app.ConfigureMvcBuilder(env); }
        );
        builder
            .Run(async c =>
                await c.Response.WriteAsync("This should work"));
    }

在后一个示例中,services 对象以 335 个描述符的 Count 结束,在前一个(工作)示例中,它有 356 个。

我尝试查看 this blog 以查看是否可以弄清楚发生了什么,但我没有看到方法中的内容与 Gordon 所描述的内容之间存在很强的相关性。所以我完全迷路了。任何帮助,将不胜感激。如果有办法拆分扩展方法并为每个管道传递服务,那对我来说很好。

是的,我知道您在这里只看到一个管道。重点是添加更多。

【问题讨论】:

  • 对于第二次遇到此问题的任何人,我以为我有答案但没有。

标签: .net-core asp.net-core-mvc


【解决方案1】:

这是我最终得到的结果:

这是解决此问题的错误方法。我需要一个正确配置的管道。我将我的 API 和 Web 项目合并为一个项目(尽管这可能无关紧要,只要所有内容都已注册)。

(由于其他原因,我添加了异步。与它无关。)

程序.cs:

        public static async Task Main(string[] args)
        {
            IWebHost webhost = CreateWebHostBuilder(args).Build();

            await webhost.CreateOrMigrateDatabase();

            await webhost.RunAsync();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            new WebHostBuilder()
                .ConfigureAppConfiguration((host, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile("appsettings.json");

                    if (host.HostingEnvironment.IsDevelopment())
                        config.AddUserSecrets<Startup>();
                    else
                        config.AddEnvironmentVariables(prefix: "MYAPP_");
                })
                .UseKestrel()
                .ConfigureLogging((app, logging) =>
                {
//snip
                })
                .UseStartup<Startup>()
                .UseUrls("http://*:4213");
    }

Startup.cs:

        public void ConfigureServices(IServiceCollection services)
        {
            var connString = Configuration.GetConnectionString("default");

            services.ConfigureJwt(_signingKey, Configuration);

            // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.2#configure-localization
            services.AddLocalization(options => options.ResourcesPath = StartupConfiguration.ResourcesFolder);

            services.AddDbContext<AppDbContext>(builder =>
            {
                builder.UseLazyLoadingProxies()
                       .UseSqlServer(connString, with => with.MigrationsAssembly("App.Data"));
            });

            services.ConfigureAuthentication(Configuration);

            var mapperConfig = new MapperConfiguration(maps =>
            {
                maps.ConfigureMvc();
                maps.ConfigureApi();
            });
            var mapper = mapperConfig.CreateMapper();
            services.AddSingleton(mapper);

            // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-2.2#configure-localization
            services.AddMvc() // (config => { config.Filters.Add(new AuthorizeFilter()); }) // <~ for JWT auth
                .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddSpaStaticFiles(angularApp =>
            {
                angularApp.RootPath = "dist"; // TODO
            }); 
//snip           
}

我拆分了地图(IMapper,不相关;它们只是为两个命名空间配置 ViewModel 的扩展方法),但我没有拆分管道。一个正确配置的管道,静态网站位于 {folder}/dist。同时运行 API 和 MVC 项目。而且管理起来要少得多。

完整代码,有兴趣的可以here

【讨论】:

猜你喜欢
  • 2022-11-15
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多