Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Autofac Web Api多租户未获取HTTPContext.Current_C#_Autofac - Fatal编程技术网

C# Autofac Web Api多租户未获取HTTPContext.Current

C# Autofac Web Api多租户未获取HTTPContext.Current,c#,autofac,C#,Autofac,我很难让Autofac.Extras.Multitenance包在两种接口实现之间进行选择 我正试图根据租户Id连接到单独的数据库,但我从Autofac的示例中获取的ItenantIdentificationsStrategy没有获得HttpContext.Current设置,因此我无法从HTTP调用中获得任何信息来做出决定。我有两个这样的配置 var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build()); mtc.

我很难让Autofac.Extras.Multitenance包在两种接口实现之间进行选择

我正试图根据租户Id连接到单独的数据库,但我从Autofac的示例中获取的
ItenantIdentificationsStrategy
没有获得
HttpContext.Current
设置,因此我无法从HTTP调用中获得任何信息来做出决定。我有两个这样的配置

var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());

mtc.ConfigureTenant(Guid.Parse("00000000-0000-0000-0000-000000000001"), b => b.RegisterInstance<DatabaseConnection>(connectionOne).As<IDatabaseConnection>().SingleInstance());                
mtc.ConfigureTenant(Guid.Parse("00000000-0000-0000-0000-000000000002"), b => b.RegisterInstance<DatabaseConnection>(connectionTwo).As<IDatabaseConnection>().SingleInstance());

var resolver = new AutofacWebApiDependencyResolver(mtc);

config.DependencyResolver = resolver;

appBuilder.UseWebApi(config);
我添加了一个简单的控制器来测试它,它应该在ASP.NET管道中

public IHttpActionResult Get(IMongoDBAdapter adapter, string memberId= null) {
     return Ok()
}
这是Autofac网站上的示例。但是HttpContext.Current始终为null,并且未设置租户Id,然后它会抱怨我的控制器没有获得
数据库连接

编辑 我想我的问题可能是这个项目没有托管在IIS中。它是一个自托管的windows服务,甚至在控制器HttpContext中也是如此。Current为null。似乎这种想法在自托管服务中不可能实现?

你是对的-

您可以将其放在自托管请求管道中的第一位,并以类似的方式设置上下文变量

也就是说,您的
DelegatingHandler
必须

  • 阅读您感兴趣的各种基于请求的参数
  • 使用
    CallContext.LogicalSetData
然后您的租户ID策略将使用
CallContext.LogicalGetData
读取该值

看看ASP.NET核心也不支持
HttpContext.Current
,因此如何

这实际上可能是一些需要更正的棘手代码,因此我将在这里放置一个非常非常粗糙的样本,但是不要复制/粘贴它,并假设它将是100%完美的。我不是在做广泛的测试,我只是想给你一个想法

以下是处理程序的外观:

public class TenantIdentityHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var id = request.Headers.GetValues("X-Tenant-ID").FirstOrDefault();
        CallContext.LogicalSetData("TenantIdentification" + AppDomain.CurrentDomain.Id, new ObjectHandle(id));
        return await base.SendAsync(request, cancellationToken);
    }
}
public class CallContextStrategy : ITenantIdentificationStrategy
{
    public bool TryIdentifyTenant(out object tenantId)
    {
        var handle = CallContext.LogicalGetData("TenantIdentification" + AppDomain.CurrentDomain.Id) as ObjectHandle;
        var tenantId = handle?.Unwrap() as string;
        return tenantId != null;
    }
}
再说一次,我还没有试过,所以你可能需要调整一下,但希望它能让你开始。

你是对的-

您可以将其放在自托管请求管道中的第一位,并以类似的方式设置上下文变量

也就是说,您的
DelegatingHandler
必须

  • 阅读您感兴趣的各种基于请求的参数
  • 使用
    CallContext.LogicalSetData
然后您的租户ID策略将使用
CallContext.LogicalGetData
读取该值

看看ASP.NET核心也不支持
HttpContext.Current
,因此如何

这实际上可能是一些需要更正的棘手代码,因此我将在这里放置一个非常非常粗糙的样本,但是不要复制/粘贴它,并假设它将是100%完美的。我不是在做广泛的测试,我只是想给你一个想法

以下是处理程序的外观:

public class TenantIdentityHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var id = request.Headers.GetValues("X-Tenant-ID").FirstOrDefault();
        CallContext.LogicalSetData("TenantIdentification" + AppDomain.CurrentDomain.Id, new ObjectHandle(id));
        return await base.SendAsync(request, cancellationToken);
    }
}
public class CallContextStrategy : ITenantIdentificationStrategy
{
    public bool TryIdentifyTenant(out object tenantId)
    {
        var handle = CallContext.LogicalGetData("TenantIdentification" + AppDomain.CurrentDomain.Id) as ObjectHandle;
        var tenantId = handle?.Unwrap() as string;
        return tenantId != null;
    }
}

同样,我还没有尝试过这个方法,因此您可能需要调整它,但希望它能让您开始。

您何时/何地解决失败的对象?(请更新问题的主体。)如果它不在请求中(例如,ASP.NET管道尚未设置HttpContext.Current),那么就没有什么可以做的了。那个doc示例只是一个示例,它周围的免责声明多得让人难以接受。您可能需要根据个人需要进行一些修改,以处理自己的特殊情况。@TravisIllig感谢您的回复和对文档的更新。然而,我没有想到要提到的一件大事是,它是在Windows服务中自托管的。不是通过IIS。似乎HttpContext.Current将始终为空,因此。。。糟糕……您何时/何地解决出现故障的对象?(请更新问题的主体。)如果它不在请求中(例如,ASP.NET管道尚未设置HttpContext.Current),那么就没有什么可以做的了。那个doc示例只是一个示例,它周围的免责声明多得让人难以接受。您可能需要根据个人需要进行一些修改,以处理自己的特殊情况。@TravisIllig感谢您的回复和对文档的更新。然而,我没有想到要提到的一件大事是,它是在Windows服务中自托管的。不是通过IIS。似乎HttpContext.Current将始终为空,因此。。。糟糕……太棒了。看来我至少可以走上正轨了。太棒了。看来我至少可以走上正轨了。