7

我正在尝试在我的站点中实现 Asp.net Forms Authentication。通常,您在 web.config 中提供数据库连接字符串的名称。但是,由于我们的数据库设置有点复杂,我一直在寻找一种方法来手动为 MembershipProvider 提供代码中的连接字符串。

谢谢!

4

2 回答 2

12

您不必使用connectionStringNamefor SqlMembershipProvider,而是可以直接提供连接字符串。即代替:

<membership defaultProvider="SqlProvider" ...>
  <providers>
    <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
         connectionStringName="MyConnectionStringName" 
         .../>
  </providers>
</membership>

您可以直接将连接字符串指定为:

<membership defaultProvider="SqlProvider" ...>
  <providers>
    <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
         connectionString="data source=... " 
         .../>
  </providers>
</membership>

因此,您还可以从 SqlMembershipProvider 派生自定义提供程序,并动态构建连接字符串,如下所示:

public class MySqlMembershipProvider : SqlMembershipProvider
{
    public override void Initialize(string name, NameValueCollection config)
    {
        config["connectionString"] = BuildMyCustomConnectionString();
        base.Initialize(name, config);
    }
}
于 2013-06-03T20:47:15.707 回答
8

我遇到了需要做同样的事情,通过代码而不是在 web.config 中设置连接字符串,虽然我需要更改的不仅仅是名称,我需要动态生成实际值。如果要更改要从代码生成的实际连接字符串,可以执行以下操作:

网络配置

...
  <connectionStrings>
    <add name="ConnectionPlaceHolder" connectionString="This is a place holder"/>
  </connectionStrings>
...
    <roleManager defaultProvider="SqlRoleProvider" enabled="true">
      <providers>
        <clear/>
        <add name="SqlRoleProvider" type="MyClassLibraries.Web.Security.MyCustomSqlRoleProvider" connectionStringName="ConnectionPlaceHolder" applicationName="MyApplicationName"/>
      </providers>
    </roleManager>

提供者类

    public class MySqlRoleProvider : SqlRoleProvider
    {
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            try
            {
                config["connectionStringName"] = "ConnectionPlaceHolder";
                base.Initialize(name, config);

                FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
                connectionStringField.SetValue(this, ApplicationConfiguration.RetrieveApplicationConfigurationValue(myConnectionString));
            }
            catch (Exception ex)
            {
                CurrentOperation.RaiseException(ex);
                throw ex;
            }
        }

        private string myConnectionString()
        {
          return "Server=MyServer;database=MyDB;uid=aspnetDBUser;pwd=myPassword"
        }
    }

当你调用 base.Initialize() 时,.NET 类需要在 web.config 中指定一个名称,这就是为什么你必须放置一些东西,所以我只使用了一个占位符,因为我知道我会在代码中覆盖它。

我们的团队这样做是因为我们需要根据不同的环境动态构建连接字符串,并且不想担心会有多个 web.config 浮动。

于 2013-11-06T15:10:42.120 回答