2009-03-08 10 views
19

私はすべての関連する質問を読みましたが、何らかの理由で正しい解決策を得ることができませんでした。何かが私の側では正しくありませんが、何が原因なのかはわかりません。私は、カスタムメンバシッププロバイダを作成しているカスタムMembershipProviderでInitializeを呼び出すにはどうすればよいですか?

は、またに私の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."); 
     } 
    } 

} 

そして私は初期化されていることに気づきましたメソッドが呼び出されていない、私はここの質問を読んで、人々は私が手動で呼び出す必要はないと言っていた、私は正しくweb.configを結んでいる場合、私は何もする必要はありませんが、それを手動で呼び出すが、私が試していたときにInvalidCastExceptionが返されたNameValueCollectionをキャストするにはgを押します。

誰でも手伝ってもらえますか?ありがとう

答えて

3

プロバイダが正しく設定されている限り(コードサンプルのように)、Initializeメソッドを自動的に呼び出す必要があります。

名前を「手動で」呼び出す方法と、NameValueCollectionをキャストしようとした場所を明確にする必要があります。それはInitializeの内部で起こりましたか?

おそらく、あなたはoverrideキーワードを忘れてはいけませんでした(私達にあなたのInitializeメソッドを示すべき、あなたをしました;-)

編集:?まあ、Initializeメソッドが細かすぎるようです。

覚えておいてください:Membershipは静的なクラスであり、構成されたプロバイダを遅延的にロードして初期化します。プロバイダの構築と、Initializeメソッドへの呼び出しは、Membership.ProviderまたはMembership.Providersのいずれかのプロパティが呼び出されるまで発生しません。ほとんどの他の静的メソッド(GetUser()など)はこれを行いますが、メンバーシップAPIが実際に使用されるまでInitializeメソッドが呼び出されないという結論になります。

これを明示的に行うか、ログインコントロールなどを使用して行いましたか?

+0

私は既に私の質問にInitializeコードを入れていますが、私はoverrideキーワードをonにしています。 – PlayKid

+0

あなたは正しいです、それは静的です、この場合はシングルトンではなく、私は自分の投稿を編集します。ありがとう! –

1

基本的流れはこのように書き、

会員クラス(静的クラス)を呼び出し、のMembershipProvider(ProviderBaseから派生抽象クラス)(あなたのケースMyMemberShipProvider中)SqlMembershipProvider道具を使用して、このようにあなたの実装を行いましたデータアクセスコードのMyMemberShipProviderのデータソースへのアクセスを許可しますが、自分で初期化を呼び出すことはありません。

初期化は、()あなたのMyMemberShipProviderを作成するときに同じようにそれをオーバーライドし、ProviderBase上の仮想メソッドであるあなたは、それをNameValueCollectionのに関係していた例外を持っていると言うあなたのコードを見ずに

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

、下記上記の方法を私に思い出させる。

希望すると、 Ray。

+0

私の質問に私のコードを含めましたが、それはあなたのものに似ていますが、問題は決して起きません。 – PlayKid

+0

実際、メンバーシップはシングルトンではなく、静的です。 –

+0

あなたは正しいです、それは静的です、この場合はシングルトンではなく、私は自分の投稿を編集します。ありがとう! –

0

カスタムメンバーシッププロバイダは自動的に初期化されますが、手動で行う必要はありません。

例外:base.Initialize方法は、以下の例外が定義されているProviderBaseクラスであることを、覚えておいてください

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


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

:私の実装では

は、初期化は以下のようにそこmetodされています。

  • System.ArgumentNullException: プロバイダの名前がnullです。
  • System.ArgumentException: プロバイダの名前の長さはゼロです。

  • のSystem.InvalidOperationException:プロバイダが がすでに初期化された後の試みは、プロバイダにSystem.Configuration.Provider.ProviderBase.Initialize(可能System.String、System.Collections.Specialized.NameValueCollection) を呼び出すように作られて 。

最後の例外はありませんか?

+0

いいえ、問題は初期化が発生しなかったため、私が行ったことは、パブリックMyMembershipProvider()としてメソッドを置くことです。それは動作しますが、それは正しい方法ではないと思います。 – PlayKid

+0

あなたのweb.configファイルに次のように持って、確認してください: タイプ= "MyNameSpace.MyMemberShipProvider、MYNAMESPACE" : <会員defaultProvider = "MyMemberShipProvider"> – twk

+0

ていることを確認し、あなたが 'タイプ' 属性が2つの部分が含まれてい「MyNameSpace」はプロバイダクラスのDLL名です。 – twk

2
私はあなたがやっていることをうまくしようとしています

は....私は次のように進めていると思う:

  • は(のMembershipProviderから
  • 設定されたweb.configファイルを継承してMyMembershipProviderというカスタムクラスを作成しましたこのイベント内
  • ...その後 )ログインを認証するために、何か(例えばを行うためのイベントを発生Webコントロールを作成し

  • )私には正しいよう、あなたはこれとwondような何かをしようとしていますコードをステップ実行中にInitialize()が呼び出されない理由を説明してください:

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

ソリューション: - 代わりにこれを使用します。

bool IsAuthorised = Membership.ValidateUser(txtLogin, txtPass); 
  • を代わりに.NETが会員静的クラスを使用することにより、あなたのためにこれをやらせる、自分でクラスのインスタンスを作成しないでくださいこれにより、アプリケーションの存続期間中、MyMemberShipProviderのインスタンスが1つだけ存在することが保証されます。独自のクラスをインスタンス化してInitialize()を呼び出すと、コードはスレッドセーフではありません。
46

Initialize()を呼び出すには、カスタムメンバーシッププロバイダを特定の方法でインスタンス化する必要があります。同様に、

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

これで、myProviderを使用すると、カスタムプロバイダのInitialize()が呼び出されます。

+3

+1ありがとうございます。外部プロジェクトからメンバーシップにアクセスしたい場合、メンバーシップはSystem.Web.Securityに属し、System.Web.dllが必要です。 – CRice

+0

さらに分かりやすくするために、 "NameOfMembershipProviderInConfig"は、MembershipProvider設定ファイルエントリの "name"プロパティと完全に一致しなければなりません。私は誤って "タイプ"のプロパティの値を入れていないし、行っていませんでした。 –

0

これは

private readonly Provider _provider; 

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

呼び出される初期化はここでは、プロバイダを初期化するためのコードで強制的に:

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

私は意志、この初期化()メソッドでいくつかの時間前に問題を抱えていましたここに投稿すると、誰かにとって参考になるかもしれません。

MyEnterprise.MyArea.MyProviders.CustomProvider 

そして、何したいですプロバイダの実装内にあるメソッドGetUserNameByEmailを使用します。

はのは、あなたがあなたのカスタムプロバイダの実装を持っている想像してみましょう。

あなたが自分でそれを呼び出しているとしてあなたのコールがある場合は、他の一方で、Initializeメソッドを起動しません
MyEnterprise.MyArea.MyProviders.CustomProvider.GetUserNameByEmail(email) 

Membership.GetUserNameByEmail(email) 

このメソッドを呼び出すには二つの方法がを通じて、あります。必要に応じてInitializeメソッドが呼び出されます。これは、ベースコンストラクタなどの上にあると想定します(詳細は掘り下げません)。

これが役に立ちます。 - E.

関連する問題