我有
Controller和IActionResult如下
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);
}
}
Startup.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类:
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个dbcontext作为CustomerContext和GeneralCompanyContext。
CustomerContext 为客户提供数据库。
GeneralCompanyContext 包含所有客户的所有数据库连接字符串。
项目开始时
services.AddEntityFramework()。AddSqlServer()从
添加连接字符串配置[“数据:DefaultConnection:MigrationConnectionString”]
自动。所以当我尝试登录Index Iactionresult时,signinmanager连接字符串始终显示Configuration [“Data:DefaultConnection:MigrationConnectionString”]连接字符串。
如何为 companyResult.ConnectionString 中的 sermanager(asp.net identity)设置连接字符串?
任何帮助将不胜感激。
感谢。
答案 0 :(得分:2)
问题在于你尝试这样做的方式,很可能它不会起作用。在进入登录方法之前,您必须提前知道公司号码,例如。将其作为查询参数传递或使用子域来决定或采用其他方法。 最近我必须在ASP.NET Core 1.0中做类似的事情。无法向您发送确切的代码,因为我最终在所有这些内容中添加了基础结构代码,但我会尝试给您一些指导。
首先要知道的是,您可以在上下文的CustomerContext
方法中替换OnConfiguring
连接字符串。这是最后的手段。
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);
}
}
现在,因为你有连接字符串,你必须在CustomerDbContext中注入Tenant
对象
在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
来缓存连接字符串,并避免对每个请求执行db调用。