首页 > 解决方案 > 如何从 Cookies/Session 更改 dbContext 数据库名称

问题描述

我有多个用户拥有自己的数据库相同架构,因此我们将他们的 ConnectionString 存储在 cookie/session 中,该解决方案将可用。

如何使用 HttpContext。通过每个请求更改 DBContext 的连接字符串的 Cookie/会话数据?

数据库上下文

public MyContext(string ConnectionString) : base(ConnectionString)
{

}

依赖注册器

  public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder)
    {
    //data layer
        var dataSettingsManager = new DataSettingsManager();
        var dataProviderSettings = dataSettingsManager.LoadSettings();
        builder.Register(c => dataSettingsManager.LoadSettings()).As<DataSettings>();
        builder.Register(x => new EfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency();

        builder.Register(x => x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency();

        if (dataProviderSettings != null && dataProviderSettings.IsValid())
        {
            var efDataProviderManager = new EfDataProviderManager(dataSettingsManager.LoadSettings());
            var dataProvider = efDataProviderManager.LoadDataProvider();
            dataProvider.InitConnectionFactory();

            builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();
        }
        else
            builder.Register<IDbContext>(c => new DBObjectContext(dataSettingsManager.LoadSettings().DataConnectionString)).InstancePerLifetimeScope();

        //repositories
        builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();

标签: c#asp.net-mvcentity-frameworkdatabase-connectiondbcontext

解决方案


您应该能够替换:

从这里: dataProviderSettings.DataConnectionString

builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();

使用一个将从 cookie 中读取值的类。

那个新类显然不会是控制器,因此HttpContext需要通过以下方式访问需求:IHttpContextAccessor

为此,请添加以下内容:

public void ConfigureServices(IServiceCollection services)
{
     //other registrations
     services.AddHttpContextAccessor();
}

然后在您的新课程中:

    public class ConnectionStringAccessor {
        private IHttpContextAccessor _httpContextAccessor;
        public ConnectionStringAccessor(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public string GetConnectionString() {
            return  _httpContextAccessor.HttpContext.Request.Cookies["cookieName"].Value;
//you can consider some encryption/decryption or whatever you need to.
        }
    }

最后:

builder.Register<IDbContext>(c => new DBObjectContext(c.Resolve<ConnectionStringAccessor >().GetConnecionString()).InstancePerLifetimeScope();

我目前没有可用的 VisualStudio,所以我在没有构建或测试的情况下放置了代码。此外,您的新课程必须在 DI 中注册。

更多信息请参考这篇文章:https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2

正如我在评论中所说,只是为了强调,处理连接字符串等敏感事物的方式非常不安全。


推荐阅读