如何在运行时使用sqlmembershipprovider的多个数据库?

时间:2014-05-15 09:23:10

标签: c# asp.net sql .net asp.net-mvc

我有一个Web应用程序和两个sql数据库。我的客户想要不同的语言,我用资源文件解决了它,一个是网站的公共部分,没有probs。问题是他们有两个数据库具有相同的结构和数据类型但是使用不同的语言,并且用户也不同。我已将SqlMembershipProvider中的“Initialize”覆盖为:

public class MyqlMembershipProvider : SqlMembershipProvider
{

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            var connectionString = GetConnectionStringFromSelectedLanguage();

            config["connectionStringName"] = connectionString;
            base.Initialize(name, config);            
        }
}

但是Initialize只被调用一次,我需要在每次使用Membership.yadayada时根据所选语言设置connectionString。我不想使用Membership.Providers["one_provider"].DeleteUser(a_username)因为它在任何地方都被使用。我该怎么做呢,还有什么我可以覆盖的吗?

/麦克

3 个答案:

答案 0 :(得分:0)

您可以为应用程序使用DependencyInjection框架Ninject,并根据命名依赖项构建存储库。

例如,您可以使用仅提供连接字符串名称的接口:

Interface IConnectionProvider
{
   ConnectionName { get;}
}

class LanguageAProvider : IConnectionProvider
{
    public string ConnectionName { get { return "dbnameLangA"; }  }
}

class LanguageBProvider : IConnectionProvider
{
    public string ConnectionName { get { return "dbnameLangB"; }  }
}

public class MyqlMembershipProvider : SqlMembershipProvider
{
    private readonly string _connectionStringName;

    public MyqlMembershipProvider (IConnectionProvider connection)
    {
        _connectionStringName = connection.ConnectionName;
    }

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            var connectionString = GetConnectionStringFromSelectedLanguage();

            config[_connectionStringName] = _connectionStringName;//I'm not sure how you need to use the connection name here.
            base.Initialize(name, config);            
        }
}

我没有测试任何这个,但它可能是一个想法。然后,您可以Named Bindings在运行时选择所需的依赖项。

答案 1 :(得分:0)

  

我每次使用Membership.yadayada时都需要设置connectionString,具体取决于所选语言

这是不可行的:考虑当同时处理来自不同语言的用户的两个请求时会发生什么。如果您更改了用户A的连接字符串,则会影响用户B.

您可以做的是编写一个自定义成员资格提供程序,它聚合两个(或更多)SqlMembershipProviders,并根据当前用户的语言进行重定向。

public class MyMembershipProvider : MembershipProvider
{
     private Dictionary<string, MembershipProvider> _languageMembeshipProviders;

     public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
        ... create an SqlMembershipProvider for each language and add to
        ... the languageMembeshipProviders dictionary
    }

    public override bool ValidateUser(...)
    {
        ... Get language from HttpContext.Current somehow
        ... select a provider from the dictionary
        ... call the provider
    }
}

但是我发现很难理解这在实践中如何发挥作用。据推测,请求中有一些东西(查询字符串,cookie,接受语言标题)来指示用户的语言。如果是这样,用户可能会使用一种语言进行身份验证,然后通过更改其请求中的语言切换到访问其他数据库。

我认为为每种语言分别创建应用程序会更简单,更清晰。如果用户到达站点A表示他想要语言B,那么他应该被重定向到应用程序B.

答案 2 :(得分:0)

这是不可能的。成员资格提供程序是一次初始化并在用户之间共享的静态对象。更改它的任何值都会为应用程序的所有用户更改它们。请参阅此答案以获得更详尽的解释...

How do I use multiple databases with sqlmembershipprovider at runtime?