Подтвердить что ты не робот

Как я могу назвать Initialize на пользовательском MembershipProvider?

Я прочитал все связанные вопросы, но по-прежнему не могу получить правильное решение, что-то не так на моей стороне, но не уверен, что его вызывает.

Я создал пользовательский поставщик членства, также изменил свой 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, я не должен сделать что-нибудь, но я попытался вызвать это вручную, но он дал мне InvalidCastException, когда я пытался использовать NameValueCollection.

Может ли кто-нибудь мне помочь? Благодаря

4b9b3361

Ответ 1

Для Инициализатора(), который должен быть вызван, вам необходимо создать экземпляр своего пользовательского поставщика членства определенным образом. Например:

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

Теперь, когда вы используете myProvider, вызывается Initialize() из вашего настраиваемого провайдера.

Ответ 2

Истинно, ваш метод Initialize должен вызываться автоматически до тех пор, пока ваш провайдер настроен правильно (как кажется, в вашем примере кода).

Вам нужно будет уточнить, как вы его назвали вручную, и где вы пытались использовать NameValueCollection. Это произошло в Initialize?

Возможно, вы должны показать нам свой метод Initialize (вы не забыли ключевое слово override, вы?; -)

Изменить: Ну, метод Initialize тоже выглядит отлично.

Имейте в виду: Membership - это статический класс, и он загружает и инициализирует настроенных поставщиков ленивым способом. Таким образом, построение вашего провайдера и вызов его метода Initialize не будут выполняться до тех пор, пока не будет выполнен вызов для свойства Membership.Provider или Membership.Providers. Большинство других статических методов (например, GetUser()) будут делать это, но вывод заключается в том, что ваш метод Initialize не будет вызываться до тех пор, пока API-интерфейс членства не будет использован.

Вы сделали это, явно или с помощью элемента управления Login или так?

Ответ 3

Я пытаюсь понять, что вы сделали... Я думаю, вы сделали следующее:

  • Создал пользовательский класс MyMembershipProvider, наследуя от MembershipProvider
  • Конфигурированный web.config(выглядит корректно для меня)
  • Создал веб-элемент управления, который запускает событие, чтобы что-то сделать (например, для аутентификации входа) Тогда...
  • В этом случае вы попытались сделать что-то вроде этого и задаетесь вопросом, почему Initialize() не вызывается при выполнении кода:

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

Решение: - Используйте это вместо:

bool IsAuthorised = Membership.ValidateUser(txtLogin, txtPass);
  • Не создавайте экземпляр своего класса самостоятельно, вместо этого пусть .NET сделает это за вас, используя статический класс Membership, который гарантирует, что на протяжении всего жизненного цикла приложения существует только один экземпляр MyMemberShipProvider. Если вы создаете экземпляр собственного класса и вызываете Initialize(), ваш код не будет потокобезопасным.

Ответ 4

В основном поток идет так,

Класс членства (статический класс) вызывает и использует MemberhipProvider (абстрактный класс, полученный из ProviderBase), который реализует SqlMembershipProvider (в вашем случае MyMemberShipProvider), таким образом, вы предоставили свою реализацию кода доступа к данным вашему источнику данных в MyMemberShipProvider, но вы не вызываете инициализацию самостоятельно.

Инициализатор() является виртуальным методом в 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, оно напоминает мне об этом методе выше.

Надеюсь, это поможет, Ray.

Ответ 5

У меня была проблема некоторое время назад с помощью этого метода Initialize(), я отправлю его здесь, это может быть полезно для кого-то.

Предположим, что у вас есть реализация вашего настраиваемого поставщика:

MyEnterprise.MyArea.MyProviders.CustomProvider

И вы хотите использовать метод GetUserNameByEmail, который находится внутри реализации поставщика. Существует два способа вызова этого метода:

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

Что не будет запускать метод Initialize, поскольку вы вызываете его самостоятельно, с другой стороны, если ваш вызов:

Membership.GetUserNameByEmail(email)

При необходимости вызывается метод Initialize, я предполагаю, что это находится в базовом конструкторе или чем-то (не выкапывает больше).

Надеюсь, это поможет. - E.

Ответ 6

Пользовательский поставщик членства инициализируется автоматически, и он не предназначен для этого вручную.

В моей реализации есть метод Initialize, как показано ниже:

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:   Имя провайдера имеет значение null.
  • System.ArgumentException:   Имя провайдера имеет длину 0.

  • System.InvalidOperationException:    Делается попытка вызвать System.Configuration.Provider.ProviderBase.Initialize(System.String, System.Collections.Specialized.NameValueCollection) на провайдере после того, как поставщик уже инициализирован.

Не последнее исключение, которое вы получили?

Ответ 7

это заставляет инициализацию называть

private readonly Provider _provider;

public AccountMembershipService(Provider provider)
{
   _provider = provider ?? (Provider) Membership.Provider;
}

Ответ 8

Вот код для инициализации провайдера:

                System.Collections.Specialized.NameValueCollection adProviderConfig;
                adProviderConfig = membershipSection.Providers[adProviderName].Parameters;
                var _ADProvider = new ActiveDirectoryMembershipProvider();
                _ADProvider.Initialize(adProviderName, adProviderConfig);