【问题标题】:.NET Core Multi Tenant localhost is null after setting.NET Core Multi Tenant localhost 设置后为空
【发布时间】:2020-01-17 20:57:04
【问题描述】:

我现在正在试用 Finbuckle 多租户库,并已设法为用户设置租户信息。

但是,当我重定向到另一个页面并在视图中加载租户信息时,它显示为 null。我做错了吗?

这就是我获取和设置租户信息的方式:

var OrganizationId = HttpContext.User.Claims.Where(xc => xc.Type == MultiTenancy.ClassLibrary.Globals.CookieGlobals.OrganizationId).Select(xc => xc.Value).SingleOrDefault();
var tenantInfo = await store.TryGetByIdentifierAsync(OrganizationId);
HttpContext.TrySetTenantInfo(tenantInfo, resetServiceProvider: true);
var ti = HttpContext.GetMultiTenantContext()?.TenantInfo;
return RedirectToAction("Sample", "Home", new { __tenant__ = tenantInfo.Name });

这是示例视图:

@using Microsoft.AspNetCore.Identity
@{
    ViewData["Title"] = "Sample";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var tenantInfo = Context.GetMultiTenantContext()?.TenantInfo;
}
@using Finbuckle.MultiTenant.AspNetCore

<h2>@tenantInfo.Name</h2>

编辑:

到目前为止,如果我这样做是有效的:

public async Task<ActionResult> Sample()
{
    var OrganizationId = HttpContext.User.Claims.Where(xc => xc.Type == MultiTenancy.ClassLibrary.Globals.CookieGlobals.OrganizationId).Select(xc => xc.Value).SingleOrDefault();
    var tenantInfo = await store.TryGetByIdentifierAsync(OrganizationId);
    HttpContext.TrySetTenantInfo(tenantInfo, resetServiceProvider: true);
    var ti = HttpContext.GetMultiTenantContext()?.TenantInfo;
    return View(ti);
}

但这意味着必须始终设置tenantinfo。有没有办法让它持久化?

这是我的 Startup.cs:

services.AddMultiTenant()
    .WithEFCoreStore<MultiTenancyDbContext, TenantInfo>()
    .WithDelegateStrategy(context => {
        var organizationId = ((HttpContext)context).User.Claims.Where(xc => xc.Type == MultiTenancy.ClassLibrary.Globals.CookieGlobals.OrganizationId).Select(xc => xc.Value).SingleOrDefault();
        return Task.FromResult(organizationId);
    });



app.UseMvc(routes =>
{
    routes.MapRoute(
      name: "areas",
      template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
    );
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}"
    );

});

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core asp.net-core-mvc multi-tenant


    【解决方案1】:

    感谢您在 GitHub 网站上联系我Finbuckle.MultiTenant

    租户信息丢失的原因是重定向到操作重定向用户浏览器,因此它就像一个全新的 HTTP 请求,基本上重置了所有内容。您发布的第二种方法实际上并没有重定向用户浏览器,因此它不会丢失信息。 Finbuckle.MultiTenant 应该适用于任何一种方法——我将在下面尝试阐明它是如何工作的。

    看起来您是在自己设置租户信息,但虽然这是可能的,但这不是预期的流程。该库的设计使其中间件可以在您的控制器代码被命中之前使用策略、查询商店并设置租户信息。它看起来像这样(在此示例中,WithStrategyWithStore 被简化了):

    // In your services configuration in your Startup class:
    services.AddMultiTenant().WithStrategy().WithStore();
    
    // In your app pipeline in your Startup class:
    app.UseMultiTenant(); // <-- This sets the tenant info
    

    所以在正常情况下,您不需要致电store.TryGetByIdentifierAsync(...)HttpContext.SetTenantInfo(...)

    相反,您想定义一个从 cookie 中获取组织 ID 的策略,就像您所做的那样。中间件将在每个请求开始时使用该策略来设置租户信息。有一个DelegateStrategy 应该适合您的情况。它要求您设置一个委托或 lambda,它将返回租户标识符,在您的情况下为组织 ID:

    services.AddMultiTenant().WithStore().
             WithDelegateStrategy(context =>
             {
                 var organizationId = HttpContext.User.Claims.Where(xc => xc.Type == MultiTenancy.ClassLibrary.Globals.CookieGlobals.OrganizationId).Select(xc => xc.Value).SingleOrDefault();
                 return Task.FromResult(organizationId);
             });
    

    请查看存储库中的 delegate strategy sample 以查看使用类似方法的工作项目。

    【讨论】:

    • 非常感谢您回答这个问题!你的委托策略奏效了。我还有另一个问题,我的网址中仍然有 ?__tenant__= 。是否可以删除它们?
    • 我将我的 Startup.cs 与代表团一起添加到问题中。它似乎有效,但只剩下 _tenant_= 参数
    • 在 Startup 的路线设置中,您有关于那里的租户的任何信息吗?如果是这样,请将其删除 - 它旨在与路由策略一起使用,但您现在没有使用该策略。
    • 我删除了 WithRouteStrategy 部分以及 app.useMvc(route.MapRoute(name:"tenant",template: "{tenant:exists}/{area:exists}/{controller=Home} /{action=Index}"));
    • 我将其添加到我的问题中。
    猜你喜欢
    • 2020-06-27
    • 1970-01-01
    • 2019-12-19
    • 2020-11-01
    • 2018-08-11
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多