2009-03-08 5 views
19

Ho letto tutte le domande correlate, ma non riesco ancora a trovare la soluzione giusta per qualche motivo, qualcosa non va dalla mia parte, ma non sono sicuro di cosa lo stia causando.Come si chiama Initialize su un MembershipProvider personalizzato?

ho creato un provider personalizzato appartenenza, anche cambiato il mio web.config per:

<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> 

Ecco il codice per il mio metodo 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."); 
     } 
    } 

} 

E ho notato che l'inizializzazione il metodo non è stato chiamato, ho letto le domande qui e le persone stavano dicendo che non devo chiamarlo manualmente, se ho cablato correttamente il mio web.config, non devo fare nulla, ma ho provato a chiamarlo manualmente, ma mi ha dato un InvalidCastException quando stavo provando g per lanciare NameValueCollection.

Qualcuno può aiutarmi? Grazie

risposta

3

È vero che il metodo di inizializzazione deve essere chiamato automaticamente fintanto che il provider è configurato correttamente (come sembra essere nell'esempio di codice).

Dovrai chiarire come hai chiamato "manualmente" e dove hai provato a lanciare NameValueCollection. È successo all'interno di Initialize?

Forse ci dovrebbe mostrare il vostro metodo Initialize (di non aver dimenticato la parola chiave override, vero ;-)

Edit:? Ebbene, il metodo Initialize sembra troppo fine.

Tenere presente: Membership è una classe statica e carica e inizializza i provider configurati in modo lazy. Pertanto, la costruzione del provider e la chiamata al suo metodo Initialize non si verificheranno fino a quando non viene effettuata una chiamata alla proprietà Membership.Provider o Membership.Providers. La maggior parte degli altri metodi statici (come GetUser()) eseguirà questa operazione, ma la conclusione è che il metodo Initialize non verrà chiamato fino a quando non viene effettivamente utilizzata l'API Membership.

Avete fatto questo, esplicitamente o utilizzando un controllo di accesso o simile?

+0

Ho già inserito il codice di inizializzazione nella mia domanda e ho attivato la parola chiave over e non si attiva, non so perché. – PlayKid

+0

Hai ragione, è statico, non un singleton in questo caso, modifico il mio post. Grazie! –

1

In sostanza il flusso va in questo modo, le chiamate

classe di appartenenza (una classe statica) e utilizza MembershipProvider (una classe astratta derivata da ProviderBase) che implementa SqlMembershipProvider (nel tuo caso MyMemberShipProvider), in tal modo si ha dato la vostra implementazione del codice di accesso ai dati all'origine dati in MyMemberShipProvider ma non si chiama l'inizializzazione.

L'inizializzazione() è il metodo virtuale su ProviderBase, quando si crea il MyMemberShipProvider si ignora è come qui di seguito

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");   
    } 
} 

Senza vedere il codice, quando si dice avere un'eccezione che ha a che fare con NameValueCollection, esso mi ricorda questo metodo sopra.

Spero che questo aiuti, Ray.

+0

Ho incluso il mio codice nella mia domanda, è simile al tuo, ma il problema è che non si accende mai. – PlayKid

+0

In realtà, l'appartenenza non è un singleton: è statica. –

+0

Hai ragione, è statico, non un singleton in questo caso, modifico il mio post. Grazie! –

0

Il provider di abbonamento personalizzato viene inizializzato automaticamente e non è destinato a farlo manualmente.

Nella mia realizzazione, v'è l'inizializzazione Metod come di seguito:

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


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

Tenete a mente, che il metodo base.Initialize è in classe ProviderBase che ha le seguenti eccezioni definite:

eccezioni:

  • System.ArgumentNullException: Il nome del provider è nullo.
  • System.ArgumentException: Il nome del provider ha una lunghezza pari a zero.

  • System.InvalidOperationException: Si è tentato di chiamare System.Configuration.Provider.ProviderBase.Initialize (System.String, System.Collections.Specialized.NameValueCollection) su un fornitore dopo che il fornitore è già stato inizializzato .

Non è l'ultima eccezione quella che si ottiene?

+0

No, il problema è Initialize non ha sparato, quindi quello che ho fatto è che ho messo un metodo come MyMembershipProvider() pubblico e funziona, ma non penso che sia il modo giusto per farlo. – PlayKid

+0

assicurarsi che, si ha quanto segue nel web.config: twk

+0

Assicurarsi, avete l'attributo 'tipo' comprende 2 parti: type = "MyNameSpace.MyMemberShipProvider, MyNamespace" dove "MyNameSpace" è il nome dll della classe del provider. – twk

2

Sto cercando di capire quello che avete fatto .... Penso che tu abbia proceduto come segue:

  • creato una classe personalizzata denominata MyMembershipProvider ereditando da MembershipProvider
  • web.config configurato (sembra corretto per me)
  • creato un controllo web che attiva un evento per fare qualcosa (ad esempio, per autenticare un login) Poi ...
  • All'interno di questo evento, si è cercato di fare qualcosa di simile e wond ering perché Initialize() non viene chiamato mentre si passa attraverso il codice:

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

Soluzione: - Utilizzare questo, invece:

bool IsAuthorised = Membership.ValidateUser(txtLogin, txtPass); 
  • Non creare un'istanza della classe da soli, invece facciamo .NET fare questo per voi utilizzando la classe statica appartenenza , che garantisce l'esistenza di una sola istanza di MyMemberShipProvider per tutta la durata dell'applicazione. Se istanziate la vostra classe e chiamate Initialize(), il vostro codice non sarà sicuro.
46

Per Initialize() da chiamare, è necessario creare un'istanza del provider di appartenenza personalizzato in un determinato modo. Così:

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

Ora quando si utilizza myProvider, viene chiamato Initialize() dal proprio provider personalizzato.

+3

+1 Grazie. Per coloro che desiderano accedere a Membership da un progetto esterno, Membership appartiene a System.Web.Security e richiede System.Web.dll. – CRice

+0

E proprio per maggiore chiarezza, "NameOfMembershipProviderInConfig" deve corrispondere esattamente alla proprietà "nome" della voce del file di configurazione MembershipProvider. Ho accidentalmente messo il valore della proprietà "type" e no-go. –

0

questo forza l'inizializzazione di essere chiamati

private readonly Provider _provider; 

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

Qui è il codice per inizializzare un provider:

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

ho avuto un problema qualche tempo fa con questo metodo Initialize(), lo farò postarlo qui potrebbe essere utile per qualcuno.

Immaginiamo di avere l'attuazione del vostro provider personalizzato on:

MyEnterprise.MyArea.MyProviders.CustomProvider 

E ciò che si desidera è utilizzare il metodo GetUserNameByEmail, che si trova all'interno della implementazione del provider. Ci sono due modi per chiamare questo metodo, attraverso:

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

Il che non si attiva il metodo di inizializzazione, come si sta chiamando da soli, d'altra parte, se la chiamata è:

Membership.GetUserNameByEmail(email) 

Il Il metodo di inizializzazione verrà chiamato se necessario, presumo che si tratti del costruttore di base o qualcosa del genere (non ho scavato di più).

Spero che questo aiuti. - E.