C# OwinContext环境没有';t包含添加的元素

C# OwinContext环境没有';t包含添加的元素,c#,asp.net-mvc,asp.net-web-api,owin,multi-tenant,C#,Asp.net Mvc,Asp.net Web Api,Owin,Multi Tenant,我正试图在我的WebAPI项目中实现多租户 在我的Startup.Auth.cs中,我正在将所选租户对象添加到IOwinContext中 app.Use(async (ctx, next) => { Tenant tenant = GetTenantBasedUrl(ctx.Request.Uri.Host); if (tenant == null) { t

我正试图在我的WebAPI项目中实现多租户

在我的Startup.Auth.cs中,我正在将所选租户对象添加到IOwinContext中

       app.Use(async (ctx, next) =>
        {
            Tenant tenant = GetTenantBasedUrl(ctx.Request.Uri.Host);
            if (tenant == null)
            {
                throw new ApplicationException("tenant not found");
            }
            ctx.Environment.Add("MultiTenant", tenant);
            await next();
        }
其中GetTenantBaseUrl函数返回所选租户对象。 我已经创建了一个实现ApicController的类,我会将它实现到我的每个控制器上,以获得租户对象

public class MultiTenantWebApiController : ApiController
{
    public Tenant Tenant
    {
        get
        {
            object multiTenant;
            IDictionary<string, object> dic =  HttpContext.Current.GetOwinContext().Environment;
            if (!HttpContext.Current.GetOwinContext().Environment.TryGetValue("MultiTenant", out multiTenant))
            {
                throw new ApplicationException("Could Not Find Tenant");
            }
            return (Tenant)multiTenant; 
        }
    }

}
有人知道为什么我没有在ApplicationAuthProvider的OwinContext.Environment中获得“MultiTenant”密钥,而我却在控制器中获得它吗


谢谢

我建议您可以使用注入到每个api控制器的上下文,以便租户及其上下文在各层中可见。上下文提供程序可以是这样的

public class ClaimsContextDataProvider : IUserContextDataProvider
    {
        public Guid UserId
        {
            get
            {
                var userId = (Thread.CurrentPrincipal as ClaimsPrincipal)?.FindFirst(ClaimTypes.Sid)?.Value;
                return TryGetGuidFromString(userId);
            }
        }
}
然后在DI框架中注册上下文提供程序[下面给出了使用Autofac的示例]

builder.RegisterType().As()

然后有一个BaseApiController,类似下面的代码片段

public Guid TenantId { get { return _userContext.TenantId; } }

        public BaseApiController(IMapper mapper, IUserContextDataProvider userContext)
        {
            _mapper = mapper;
            _userContext = userContext;
        }
访问派生控制器[CountriesController.cs]内BaseApiController的TenantId属性

// POST api/countries
        public async Task<HttpResponseMessage> PostCountry(CountryRequestModel requestModel)
        {
            Country country = _mapper.Map<CountryRequestModel, Country>(requestModel);
            country.CreatedOn = DateTimeOffset.Now;
            country.TenantId = TenantId;

            await _countryService.AddAsync(country);

            CountryDto countryDto = _mapper.Map<Country, CountryDto>(country);
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, countryDto);
            response.Headers.Location = GetCountryLink(country.Id);

            return response;
        }
//发布api/国家/地区
公共异步任务PostCountry(CountryRequestModel requestModel)
{
Country-Country=\u mapper.Map(requestModel);
country.CreatedOn=DateTimeOffset.Now;
country.TenantId=TenantId;
wait\u countryService.AddAsync(国家);
CountryDto CountryDto=\u mapper.Map(国家);
HttpResponseMessage response=Request.CreateResponse(HttpStatusCode.Created,countryDto);
response.Headers.Location=GetCountryLink(country.Id);
返回响应;
}
您可以查看下面链接中给出的示例应用程序和模板


这里的解释有点深奥,请随意阅读文档。。感谢您提供详细的文档。谢谢你@塔鲁诺赫里:如果你觉得它有用,请把它标记为答案
// POST api/countries
        public async Task<HttpResponseMessage> PostCountry(CountryRequestModel requestModel)
        {
            Country country = _mapper.Map<CountryRequestModel, Country>(requestModel);
            country.CreatedOn = DateTimeOffset.Now;
            country.TenantId = TenantId;

            await _countryService.AddAsync(country);

            CountryDto countryDto = _mapper.Map<Country, CountryDto>(country);
            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, countryDto);
            response.Headers.Location = GetCountryLink(country.Id);

            return response;
        }