我已经阅读了所有相关的问题,但由于某种原因我仍然无法得到正确的解决方案,有些事情不适合我,但不确定是什么导致了它。
我创建了一个自定义成员资格提供程序,也将我的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。
任何人都可以帮助我吗?感谢
答案 0 :(得分:46)
要调用Initialize(),您需要以某种方式实例化自定义成员资格提供程序。像这样:
MyCustomMembershipProvider myProvider = (MyCustomMembershipProvider)Membership.Providers["NameOfMembershipProviderInConfig"];
现在,当您使用myProvider时,将调用自定义提供程序中的Initialize()。
答案 1 :(得分:3)
只要您的提供程序配置正确(因为它似乎在您的代码示例中),就应该自动调用Initialize方法。
您需要澄清“手动调用它”的方式,以及尝试转换NameValueCollection的位置。它是在Initialize内发生的吗?
也许您应该向我们展示您的Initialize方法(您没有忘记override
关键字,是吗?; - )
编辑:嗯,Initialize方法似乎也很好。
请记住:Membership
是一个静态类,它以惰性方式加载和初始化已配置的提供程序。因此,在调用Initialize
或Membership.Provider
属性之前,不会发生提供程序的构造以及对其Membership.Providers
方法的调用。大多数其他静态方法(例如GetUser()
)都会这样做,但结论是在实际使用Membership API之前不会调用Initialize方法。
您是否已明确或使用Login控件等完成此操作?
答案 2 :(得分:2)
我想弄清楚你做了什么......我认为你已经按照以下步骤进行:
在这个事件中,你试图做这样的事情并想知道为什么在单步执行代码时没有调用Initialize():
MyNameSpace.MyMemberShipProvider msp = new MyNameSpace.MyMemberShipProvider();
bool IsAuthorised = msp.ValidateUser(txtLogin,txtPass);
解决方案: - 改用它:
bool IsAuthorised = Membership.ValidateUser(txtLogin, txtPass);
答案 3 :(得分:1)
基本上流程就是这样,
成员资格类(静态类)调用并使用SqlMembershipProvider实现的MembershipProvider(派生自ProviderBase的抽象类)(在您的情况下为MyMemberShipProvider),因此您将数据访问代码的实现提供给MyMemberShipProvider中的数据源但是你不要自己打电话给初始化。
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有关的异常时,它会让我想起上面的这个方法。
希望这有帮助, 射线。
答案 4 :(得分:1)
前一段时间我用这个Initialize()方法遇到了问题,我会在这里发布它可能对某人有帮助。
让我们假设您已经实现了自定义提供程序:
MyEnterprise.MyArea.MyProviders.CustomProvider
您想要的是使用提供程序实现中的方法GetUserNameByEmail。有两种方法可以通过以下方式调用此方法:
MyEnterprise.MyArea.MyProviders.CustomProvider.GetUserNameByEmail(email)
如果您的电话是:
,那么您自己调用的方法不会触发Initialize方法。Membership.GetUserNameByEmail(email)
如果需要,将调用Initialize方法,我假设这是在基础构造函数或其他东西上(没有挖掘更多)。
希望这会有所帮助。 - E.
答案 5 :(得分:0)
自定义成员资格提供程序会自动初始化,而不是手动初始化。
在我的实现中,有如下的Initialize metod:
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.ArgumentException: 提供者的名称长度为零。
System.InvalidOperationException: 尝试调用System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection) 提供商之后的提供商 已经初始化。
你得到的那个不是最后一个例外吗?
答案 6 :(得分:0)
这会强制调用初始化
private readonly Provider _provider;
public AccountMembershipService(Provider provider)
{
_provider = provider ?? (Provider) Membership.Provider;
}
答案 7 :(得分:0)
以下是初始化提供商的代码:
System.Collections.Specialized.NameValueCollection adProviderConfig;
adProviderConfig = membershipSection.Providers[adProviderName].Parameters;
var _ADProvider = new ActiveDirectoryMembershipProvider();
_ADProvider.Initialize(adProviderName, adProviderConfig);