19

我已经阅读了所有相关的问题,但由于某种原因我仍然无法得到正确的解决方案,我这边有些不对劲,但不确定是什么原因造成的。

我创建了一个自定义成员资格提供程序,还将我的 web.config 更改为:

   <membership defaultProvider="MyMemberShipProvider">
      <providers>
        <clear />
        <add name="MyMemberShipProvider" 
                  type="MyNameSpace.MyMemberShipProvider" 
                  connectionStringName="ApplicationServices" 
                  enablePasswordRetrieval="false" 
                  enablePasswordReset="true" 
                  requiresQuestionAndAnswer="false" 
                  requiresUniqueEmail="false" 
                  passwordFormat="Hashed" 
                  maxInvalidPasswordAttempts="5" 
                  minRequiredPasswordLength="6" 
                  minRequiredNonalphanumericCharacters="0" 
                  passwordAttemptWindow="10" 
                  passwordStrengthRegularExpression="" 
                  applicationName="MyApplication" />
      </providers>
    </membership>

这是我的 Initialize 方法的代码:

public override void Initialize(string name, NameValueCollection config)
{
    if (config == null)
    { throw new ArgumentNullException("config"); }

    if (string.IsNullOrEmpty(name))
    { name = "MyMemberShipProvider"; }

    if (string.IsNullOrEmpty(config["description"]))
    {
        config.Remove("description");
        config.Add("description", "My Membership Provider");
    }

    base.Initialize(name, config);

    _applicationName = GetConfigValue(config["applicationName"], System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
    _maxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
    _passwordAttemptWindow = Convert.ToInt32(GetConfigValue(config["passwordAttemptWindow"], "10"));
    _minRequiredNonAlphaNumericCharacters = Convert.ToInt32(GetConfigValue(config["minRequiredAlphaNumericCharacters"], "1"));
    _minRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config["minRequiredPasswordLength"], "7"));
    _passwordStregthRegularExpression = Convert.ToString(GetConfigValue(config["passwordStrengthRegularExpression"], String.Empty));
    _enablePasswordReset = Convert.ToBoolean(GetConfigValue(config["enablePasswordReset"], "true"));
    _enablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config["enablePasswordRetrieval"], "true"));
    _requiredQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config["requiresQuestionAndAnswer"], "false"));
    _requiredUniqueEmail = Convert.ToBoolean(GetConfigValue(config["requiresUniqueEmail"], "true"));

    string temp_format = config["passwordFormat"];
    if (temp_format == null)
    {
        temp_format = "Hashed";
    }

    switch (temp_format)
    {
        case "Hashed":
            _passwordFormat = MembershipPasswordFormat.Hashed;
            break;
        case "Encrypted":
            _passwordFormat = MembershipPasswordFormat.Encrypted;
            break;
        case "Clear":
            _passwordFormat = MembershipPasswordFormat.Clear;
            break;
        default:
            throw new ProviderException("Password format not supported.");
    }

    ConnectionStringSettings _connectionStringSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];

    if (_connectionStringSettings == null || _connectionStringSettings.ConnectionString.Length == 0)
    {
        throw new ProviderException("Connection String Cannot Be Blank.");
    }

    _connectionString = _connectionStringSettings.ConnectionString;

    //Get Encryption and Decryption Key Information From the Information.

    System.Configuration.Configuration cfg = WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
    _machinekey = cfg.GetSection("system.web/machineKey") as MachineKeySection;

    if (_machinekey.ValidationKey.Contains("AutoGenerate"))
    {
        if (PasswordFormat != MembershipPasswordFormat.Clear)
        {
            throw new ProviderException("Hashed or Encrypted passwords are not supported with auto-generated keys.");
        }
    }

}

而且我注意到没有调用 Initialize 方法,我通读了这里的问题,人们说我不必手动调用它,如果我正确连接了我的 web.config,我不必这样做任何东西,但我确实尝试手动调用它,但是当我尝试投射 NameValueCollection 时它给了我一个 InvalidCastException。

谁能帮我?谢谢

4

8 回答 8

46

For Initialize() to be called, you will need to instantiate your custom membership provider a certain way. Like so:

MyCustomMembershipProvider myProvider = (MyCustomMembershipProvider)Membership.Providers["NameOfMembershipProviderInConfig"];

Now when you use myProvider, Initialize() from your custom provider will be called.

于 2009-10-20T20:14:27.423 回答
3

确实,只要您的提供程序配置正确(正如您的代码示例中所示),您的 Initialize 方法就应该自动调用。

您需要澄清您是如何“手动调用它”的,以及您尝试在何处转换 NameValueCollection。它发生在初始化内部吗?

也许您应该向我们展示您的 Initialize 方法(您没有忘记override关键字,是吗?;-)

编辑:好吧, Initialize 方法似乎也很好。

请记住:Membership是一个静态类,它以惰性方式加载和初始化配置的提供程序。因此,在调用 the或属性之前,您的提供者的构造以及对其Initialize方法的调用将不会发生。大多数其他静态方法(例如)都会这样做,但结论是在实际使用 Membership API 之前不会调用您的 Initialize 方法。Membership.ProviderMembership.ProvidersGetUser()

您是否已明确地或通过使用登录控件或类似方式完成此操作?

于 2009-03-08T13:37:17.900 回答
2

我正在努力弄清楚你做了什么......我认为你已经进行了如下操作:

  • 通过从 MembershipProvider 继承创建了一个名为 MyMembershipProvider 的自定义类
  • 配置的 web.config(对我来说看起来正确)
  • 创建了一个 Web 控件,它触发一个事件来做某事(例如验证登录)然后......
  • 在此事件中,您尝试执行类似的操作,并想知道为什么在单步执行代码时未调用 Initialize():

    MyNameSpace.MyMemberShipProvider msp = new MyNameSpace.MyMemberShipProvider();
    bool IsAuthorised = msp.ValidateUser(txtLogin, txtPass);

解决方案: - 改用这个:

bool IsAuthorised = Membership.ValidateUser(txtLogin, txtPass);
  • 不要自己创建类的实例,而是让 .NET 使用 Membership 静态类为您完成此操作,这可确保在应用程序的整个生命周期中只存在一个 MyMemberShipProvider 实例。如果您实例化自己的类并调用 Initialize(),您的代码将不是线程安全的。
于 2009-05-30T12:28:46.777 回答
1

基本上流程是这样的,

Membership 类(静态类)调用并使用 SqlMembershipProvider 实现的 MembershipProvider(派生自 ProviderBase 的抽象类)(在您的情况下为 MyMemberShipProvider),因此您将数据访问代码的实现提供给 MyMemberShipProvider 中的数据源,但您没有t自己调用初始化。

Initialize() 是 ProviderBase 上的虚拟方法,当您创建 MyMemberShipProvider 时,您将覆盖它,如下所示

class MyMemberShipProvider : MembershipProvider
{
    private string _connectionStringName;

    public override void Initialize(string name, NameValueCollection config)
    {
       // see the config parameter passed in is of type NameValueCollection 
       // it gives you the chance to get the properties in your web.config
       // for example, one of the properties is connectionStringName

        if (config["connectionStringName"] == null)
        {
            config["connectionStringName"] = "ApplicationServices";
        }
        _connectionStringName = config["connectionStringName"];
        config.Remove("connectionStringName");          
    }
}

没有看到你的代码,当你说有一个与 NameValueCollection 有关的异常时,它让我想起了上面的这个方法。

希望这会有所帮助,雷。

于 2009-03-08T14:12:03.493 回答
1

前段时间我遇到了这个 Initialize() 方法的问题,我会在这里发布它可能对某人有帮助。

假设您在以下位置实现了自定义提供程序:

MyEnterprise.MyArea.MyProviders.CustomProvider

您想要的是使用提供程序实现中的 GetUserNameByEmail 方法。有两种方法可以调用这个方法,通过:

MyEnterprise.MyArea.MyProviders.CustomProvider.GetUserNameByEmail(email)

在您自己调用它时,它不会触发 Initialize 方法,另一方面,如果您的调用是:

Membership.GetUserNameByEmail(email)

如有必要,将调用 Initialize 方法,我假设这是在基本构造函数或其他东西上(没有挖掘更多)。

希望这可以帮助。- E。

于 2014-02-21T17:29:51.187 回答
0

自定义成员资格提供程序是自动初始化的,并不打算手动进行。

在我的实现中,有如下初始化方法:

public override void Initialize(string name, NameValueCollection config)
{
    if (config == null)
        throw new ArgumentNullException("config");


    // Initialize the abstract base class.
    base.Initialize(name, config);
}

请记住,base.Initialize 方法位于 ProviderBase 类中,该类定义了以下异常:

例外:

  • System.ArgumentNullException:提供者的名称为空。
  • System.ArgumentException:提供者的名称长度为零。

  • System.InvalidOperationException:在提供程序已初始化后,尝试在提供程序上调用 System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)。

你得到的不是最后一个例外吗?

于 2009-03-08T14:23:28.210 回答
0

这会强制调用初始化

private readonly Provider _provider;

public AccountMembershipService(Provider provider)
{
   _provider = provider ?? (Provider) Membership.Provider;
}
于 2013-03-07T14:54:59.783 回答
0

这是初始化提供程序的代码:

                System.Collections.Specialized.NameValueCollection adProviderConfig;
                adProviderConfig = membershipSection.Providers[adProviderName].Parameters;
                var _ADProvider = new ActiveDirectoryMembershipProvider();
                _ADProvider.Initialize(adProviderName, adProviderConfig);
于 2014-01-01T12:08:50.397 回答