我有
控制器和 IAction结果如下
public HomeController(
UserManager<CustomerApplicationUser> userManager,
SignInManager<CustomerApplicationUser> signInManager,
IMemoryCache cache)
{
_userManager = userManager;
_signInManager = signInManager;
_cache = cache;
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var companyResult = new Company();
using (var GeneralCompanyContext = new GeneralCompanyContext())
{
companyResult = await GeneralCompanyContext.Company.FirstOrDefaultAsync(t => t.CompanyNumber == model.CompanyNumber);
}
using (var context = new CustomerContext(companyResult.ConnectionString))
{
var LoginResult = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, lockoutOnFailure: false);
}
}
启动.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework().AddSqlServer()
.AddDbContext<CustomerContext>()
.AddDbContext<GeneralCompanyContext>();
services.AddIdentity<CustomerApplicationUser, IdentityRole>().AddEntityFrameworkStores<CustomerContext>().AddDefaultTokenProviders();
services.AddIdentity<GeneralCompanyApplicationUser, IdentityRole>().AddEntityFrameworkStores<GeneralCompanyContext>().AddDefaultTokenProviders();
}
客户上下文类:
CustomerContext : : IdentityDbContext<CustomerApplicationUser>
{
private readonly string _ConnectionString;
public CustomerContext()
{
_ConnectionString = Configuration["Data:DefaultConnection:MigrationConnectionString"]).ToString();
}
public CustomerContext(string ConnectionString)
{
_ConnectionString = ConnectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_ConnectionString);
base.OnConfiguring(optionsBuilder);
}
}
问题:
我有 2 个数据库上下文作为客户上下文和一般公司上下文。
CustomerContext有客户的数据库。
GeneralCompanyContext 包含所有客户的所有数据库连接字符串。
项目开始时间
服务业。AddEntityFramework()。AddSqlServer() 添加连接字符串来自
配置["数据:默认连接:迁移连接字符串"]
自动。因此,当我尝试登录索引Iactionresult时,signinmanager连接字符串始终显示配置["数据:默认连接:迁移连接字符串"]连接字符串。
如何从公司结果中为您设置连接字符串(asp.net 身份)?
任何帮助将不胜感激。
谢谢。
问题是你尝试这样做的方式,很可能是行不通的。在输入登录方法之前,您必须提前知道公司编号,例如将其作为查询参数传递或使用子域来决定或其他方法。我最近不得不在Core 1.0 ASP.NET 做类似的事情。无法发布确切的代码,因为我最终围绕所有这些添加了基础结构代码,但我会尝试为您提供一些指导。
首先要知道的是,可以在上下文的 OnConfiguring
方法中替换CustomerContext
连接字符串。这是最后的手段。
源。
public class CustomerDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// optionsBuilder.UseSqlServer("Your connection string should injected here.");
}
}
下一步是了解何时何地从 GeneralCompanyDatabase 获取连接字符串。这应该发生在相当于 MVC 5 中的 BeginRequest 中 - 在中间件中。
public class Tenant
{
public string CustomerConnectionString { get; set; }
}
public class TenantMiddleware
{
private readonly RequestDelegate next_;
public TenantMiddleware(RequestDelegate next)
{
next_ = next;
}
public async Task Invoke(HttpContext httpContext, GeneralCompanyContext companyContext)
{
// You have to know your company number here somehow !!
string customerConnectionString = await companyContext.Company.FirstOrDefaultAsync(t => t.CompanyNumber == 1).ConnectionString;
Tenant tenant = new Tenant{ CustomerConnectionString = customerConnectionString };
httpContext.Items["customerTenant"] = tenant;
await next_(httpContext);
}
}
现在,有了连接字符串,您必须使Tenant
对象在 CustomerDbContext 中可注入
在Startup.cs
services.AddScoped(prov =>
prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenant());
GetTenant()
是 HttpContext 的扩展方法。
public static Tenant GetTenant(this HttpContext context)
{
object myObj;
if (context.Items.TryGetValue("customerTenant", out myObj))
{
return myObj as Tenant;
}
return null;
}
现在,您的 CustomerDbContext 应如下所示:
public class CustomerDbContext : DbContext
{
private Tenant tenant_;
public CustomerDbContext(Tenant tenant)
{
tenant_ = tenant;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(tenant.CustomerConnectionString);
}
}
此时,SignInManager
将使用正确的连接字符串。但是你开始的方式,我非常怀疑你会让它发挥作用。因为尝试替换连接字符串的位置,所有内容都已实例化和配置。同样,我只是手动键入代码片段来说明这个想法。此外,请考虑使用中间件中的IMemoryCache
来缓存连接字符串,并避免对每个请求执行数据库调用。