【问题标题】:HttpContext always returns nullHttpContext 总是返回 null
【发布时间】:2018-11-18 21:58:11
【问题描述】:

我遇到了 HttpContext 总是返回 null 的问题。我在下面粘贴了我的代码。我在网上寻找了一个解决方案,虽然有很多我正在尝试做的事情的例子,但我无法解决它。谁能告诉我我做错了什么或其他可能导致这种情况的原因?

public class DatabaseTenantProvider : ITenantProvider
{
    private Guid _tenantId;

    public DatabaseTenantProvider(TenantContext context, IHttpContextAccessor accessor)
    {
        //this is always null
        var host = accessor.HttpContext.Request.Host.Value;

         _tenantId = context.GetTenantId(host);
    }
}

在我的创业课上,我有...

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

【问题讨论】:

  • 你在哪里访问DatabaseTenantProvider类?
  • 来自我的主要上下文。 modelBuilder.Entity
  • 你是从后台线程调用DbContext吗?
  • 我将 DatabaseTenantProvider 注入到我的主数据库上下文中,以便获取当前的tenantId。我有一个名为“TenantsContext”的第二个数据库上下文,它被注入到 DatabaseTenantProvider 类中。 “TenantsContext”包含方法“GetTenantId”,该方法获取主机并使用它来查询数据库并找到与当前主机头关联的租户 ID。我的问题是 HttpContext 始终为空(当我尝试在 DatabaseTenantProvider 类中访问它时 - 如上所示),这意味着我无法将主机头传递给 GetTenantId 方法。
  • 谁能帮我解决这个问题?

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


【解决方案1】:

您不应在类的构造函数中使用 IHttpContextAccessor。您应该保留它并使用它来获取租户 ID,如下所示:

public class DatabaseTenantProvider : ITenantProvider
{
    public DatabaseTenantProvider(TenantContext context, IHttpContextAccessor accessor)
    {
        _contextAccessor = accessor; 
    }

    private readonly IHttpContextAccessor _contextAccessor;

    public Guid GetTenantId(TenantContext context)
    {
        var host = _contextAccessor.HttpContext.Request.Host.Value;
        return context.GetTenantId(host);
     }
}

【讨论】:

  • 我也尝试过,因为这是大多数示例所推荐的。但是,它仍然返回 null。
  • 绝对不应在任何情况下在构造函数中使用 HttpContextAccessor。您必须保留它并在可能的最后一刻使用它来解析您的租户,以便在解析时有一个 Web 请求。如果您将 DatabaseTenantProvider 作为 Singleton 注入,这一点尤其重要。我可以告诉你我的 [开源项目](cloudscribe.com)中有already solved multi-tenancy
  • 我一定会的。谢谢。
【解决方案2】:

我在我的 DbInitializer 类中调用了一个方法,如果数据库不存在和/或未填充数据,它会创建并播种数据库。我将我的两个数据库上下文都传递给这个方法,如下所示。

public static void Main(string[] args)
    {
        var host = BuildWebHost(args);

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            try
            {

                var context = services.GetRequiredService<PrimaryContext>();
                var tenantContext = services.GetRequiredService<SecondaryContext>();
                DbInitializer.Initialize(primaryContext, secondaryContext);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred while seeding the database.");
            }
        }

        host.Run();
    }

调用 GetRequiredService 方法将上下文传递给 Initialize 方法导致 IHttpContextAccessor 在我的 DatabaseTenantProvider 类中返回 null。我不完全清楚为什么会发生这种情况,所以如果有人可以在下面的评论中解释/澄清,我将不胜感激。

【讨论】:

  • 我也有类似的问题:(
猜你喜欢
  • 2015-03-29
  • 2014-03-04
  • 2016-11-02
  • 2014-05-06
  • 2012-06-05
  • 2014-05-30
  • 2014-02-23
  • 2017-10-12
  • 2013-08-16
相关资源
最近更新 更多