用户登录时,ASP.NET Core更改EF连接字符串
经过几个小时的研究,发现无法做到这一点;是时候提问了.
我有一个使用EF Core和MVC的ASP.NET Core 1.1项目,供多个客户使用.每个客户都有自己的数据库,具有完全相同的模式.该项目目前是一个迁移到Web的Windows应用程序.在登录屏幕上,用户有三个字段,公司代码,用户名和密码.我需要能够在用户尝试根据他们在公司代码输入中键入的内容进行登录时更改连接字符串,然后在整个会话期间记住他们的输入. 我找到了一些方法可以使用一个数据库和多个模式执行此操作,但没有一个使用相同模式的多个数据库.
回应Herzl的回答 这似乎可行.我试图让它实现.我正在做的一件事是使用访问我的上下文的存储库类.我的控制器将注入的存储库注入其中以调用访问上下文的存储库中的方法.我如何在存储库类中执行此操作.我的存储库中没有OnActionExecuting重载.此外,如果会话持续存在,当用户再次向应用程序打开浏览器并且仍然使用持续7天的cookie登录时会发生什么?这不是新会议吗?听起来像应用程序会抛出异常,因为会话变量将为null,因此没有完整的连接字符串.我想我也可以将它存储为一个Claim,如果session变量为null,则使用Claim. 这是我的存储库类. IDbContextService是ProgramContext,但我开始添加你的建议,试着让它工作. public class ProjectRepository : IProjectRepository { private IDbContextService _context; private ILogger<ProjectRepository> _logger; private UserManager<ApplicationUser> _userManager; public ProjectRepository(IDbContextService context,ILogger<ProjectRepository> logger,UserManager<ApplicationUser> userManger) { _context = context; _logger = logger; _userManager = userManger; } public async Task<bool> SaveChangesAsync() { return (await _context.SaveChangesAsync()) > 0; } } 回应FORCE JB的回答 我试图实施你的方法.我在Program.cs上得到一个例外 host.Run(); 这是我的’Program.cs’课程.不变. using System.IO; using Microsoft.AspNetCore.Hosting; namespace Project { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } } 还有我的’Startup.cs’课程. using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using Project.Entities; using Project.Services; namespace Project { public class Startup { private IConfigurationRoot _config; public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json") .AddEnvironmentVariables(); _config = builder.Build(); } public void ConfigureServices(IServiceCollection services) { services.AddSingleton(_config); services.AddIdentity<ApplicationUser,IdentityRole>(config => { config.User.RequireUniqueEmail = true; config.Password.RequireDigit = true; config.Password.RequireLowercase = true; config.Password.RequireUppercase = true; config.Password.RequireNonAlphanumeric = false; config.Password.RequiredLength = 8; config.Cookies.ApplicationCookie.LoginPath = "/Auth/Login"; config.Cookies.ApplicationCookie.ExpireTimeSpan = new TimeSpan(7,0); // Cookies last 7 days }) .AddEntityFrameworkStores<ProjectContext>(); services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>,AppClaimsPrincipalFactory>(); services.AddScoped<IProjectRepository,ProjectRepository>(); services.AddTransient<MiscService>(); services.AddLogging(); services.AddMvc() .AddJsonOptions(config => { config.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); } public void Configure(IApplicationBuilder app,ILoggerFactory loggerFactory) { Dictionary<string,string> connStrs = new Dictionary<string,string>(); connStrs.Add("company1","1stconnectionstring")); connStrs.Add("company2","2ndconnectionstring"; DbContextFactory.SetDConnectionString(connStrs); //app.UseDefaultFiles(); app.UseStaticFiles(); app.UseIdentity(); app.UseMvc(config => { config.MapRoute( name: "Default",template: "{controller}/{action}/{id?}",defaults: new { controller = "Auth",action = "Login" } ); }); } } } 例外: InvalidOperationException: Unable to resolve service for type 'Project.Entities.ProjectContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[Project.Entities.ApplicationUser,Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole,Project.Entities.ProjectContext,System.String]'. 不知道该怎么做. 部分成功编辑 好的,我让你的例子工作了.我可以使用不同的id在我的存储库构造函数中设置连接字符串.我现在的问题是登录并选择正确的数据库.我想过从会话或声明中获取存储库,无论是非空的.但是我无法在Login控制器中使用SignInManager之前设置该值,因为SignInManager被注入到控制器中,在我更新会话变量之前创建了一个上下文.我能想到的唯一方法是登录两页.第一页将询问公司代码并更新会话变量.第二页将使用SignInManager并将存储库注入到控制器构造函数中.这将在第一页更新会话变量后发生.这实际上可能在两个登录视图之间使用动画更具视觉吸引力.除非有任何想法在没有两个登录视图的情况下执行此操作,否则我将尝试实现两页登录并发布代码(如果有效). 它实际上是破碎的 当它工作时,这是因为我仍然有一个有效的cookie.我会运行该项目,它将跳过登录.现在我收到异常InvalidOperationException:清除缓存后,没有为此DbContext配置数据库提供程序.我已经完成了所有操作并正确创建了上下文.我的猜测是身份存在某种问题.下面的代码添加实体框架存储在ConfigureServices中会导致问题吗? services.AddIdentity<ApplicationUser,IdentityRole>(config => { config.User.RequireUniqueEmail = true; config.Password.RequireDigit = true; config.Password.RequireLowercase = true; config.Password.RequireUppercase = true; config.Password.RequireNonAlphanumeric = false; config.Password.RequiredLength = 8; config.Cookies.ApplicationCookie.LoginPath = "/Company/Login"; config.Cookies.ApplicationCookie.ExpireTimeSpan = new TimeSpan(7,0); // Cookies last 7 days }) .AddEntityFrameworkStores<ProgramContext>(); 编辑 我验证了身份是问题所在.我在执行PasswordSignInAsync之前从我的存储库中提取数据,并且它提取数据就好了.如何为Identity创建DbContext? 解决方法
创建一个DbContext工厂
public static class DbContextFactory { public static Dictionary<string,string> ConnectionStrings { get; set; } public static void SetConnectionString(Dictionary<string,string> connStrs) { ConnectionStrings = connStrs; } public static MyDbContext Create(string connid) { if (!string.IsNullOrEmpty(connid)) { var connStr = ConnectionStrings[connid]; var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); optionsBuilder.UseSqlServer(connStr); return new MyDbContext(optionsBuilder.Options); } else { throw new ArgumentNullException("ConnectionId"); } } } 初始化DbContext工厂 在startup.cs中 public void Configure() { Dictionary<string,string>(); connStrs.Add("DB1",Configuration["Data:DB1Connection:ConnectionString"]); connStrs.Add("DB2",Configuration["Data:DB2Connection:ConnectionString"]); DbContextFactory.SetConnectionString(connStrs); } 用法 var dbContext= DbContextFactory.Create("DB1"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 在代码中设置PageSize时,DataPager停止工作
- asp.net-mvc – 防止在asp.net MVC 3中验证部分表单
- ASP.NET会员密码重置
- asp.net – asp服务器错误’无法加载文件或程序集’,但程序
- asp.net-mvc-4 – 如何在MVC 4中创建自定义WebSecurity.Log
- vbscript – 服务器端注释:ASP Classic中相当于<% - - %
- asp.net-mvc – 网络中的反思和表现
- asp.net-mvc – ASP.NET MVC API或WCF API
- asp.net – .NET PrivateFontCollection – 完成后如何释放
- asp.net-mvc – ASP.NET DisplayFormat dd / MM / yyyy无效
- asp.net – ResolveUrl / Url.Content在Classic
- asp.net – 通过VB.NET将click事件添加到按钮以激
- asp.net-mvc-4 – 移植到MVC4后,Windows Azure U
- ado.net – ASP.NET:如何从web.config Connecti
- 一个类如何实现两个接口中同名同参数不同返回值的
- asp.net – Context.ession对象在Application_Ac
- asp.net-mvc – MVC 5 Owin Facebook Auth导致空
- asp.net-core – 使用新的signalR for DotNet核心
- asp.net – 通过Web界面查看事件日志
- asp.net-mvc – 处理MVC中的无效URL