asp.net 4.5 custom membership provider configuration throws strange exception [duplicate]
I use my own custom Membership and Role providers in Since MVC2 and ran into this issue when I migrated from MVC3 to 4.
I created a new project in MVC4 / .net4.5 EF5 and had the miss-fortune to encounter this error.
I managed to fix it by doing the following:
Add this to your webconfig appsettings:
<appSettings> <add key="enableSimpleMembership" value="false"/> <add key="autoFormsAuthentication" value="false"/> </appSettings>
Add your connection string to your memberships and roles providers if not already set:
<membership defaultProvider="MyMembershipProvider"> <providers> <add name="MyMembershipProvider" type="AMS.WebUI.Infrastructure.CustomMembershipProvider" connectionStringName="EFDbContext" /> </providers></membership><roleManager defaultProvider="MyRoleprovider"> <providers> <add name="MyRoleprovider" type="AMS.WebUI.Infrastructure.CustomRoleProvider" connectionStringName="EFDbContext" /> </providers></roleManager>
This resolved the issue for me and I hope it can help you.
OK let's see if I can explain this right. ASP.NET 4 introduced a new assembly-level attribute: PreApplicationStartMethodAttribute
, that is typically used in the Properties/AssemblyInfo.cs
file.
ASP.NET MVC 4 standard template comes with a reference to the WebMatrix.WebData
assembly. Looking at its code, the AssemblyInfo does have this:
[assembly: PreApplicationStartMethod(typeof(PreApplicationStartCode), "Start")]
So basically, before App_Start is even invoked, the framework will call WebMatrix.WebData.PreApplicationStartCode.Start()
which, among other things, does this
// Initialize membership providerWebSecurity.PreAppStartInit();
And sure enough, like @Ben Pretorius said, that method starts like this
internal static void PreAppStartInit(){ // Allow use of <add key="EnableSimpleMembershipKey" value="false" /> to disable registration of membership/role providers as default. if (ConfigUtil.SimpleMembershipEnabled) { ...
So there you have how/why this "automatically" fails. It's really too bad that Microsoft didn't include <add key="EnableSimpleMembershipKey" value="true" />
in the standard Web.config to make it more obvious that "hey there's this SimpleProvider stuff that's setup here".
I was also playing around this a bit and looking into the WebMatrix code and finally I think that Ben's solution seems to be the working one.
(I have also tried to play with the assembly references without success. I think with removing the references you just achieved the same as the config settings does - the WebMatrix security was not properly initialized. But I think this is quite a dangerous way. But I'm just guessing here.)
So for me what worked:
<appSettings> <add key="enableSimpleMembership" value="false"/></appSettings><membership defaultProvider="MyMembershipProvider"> <providers> <clear /> <add name="MyMembershipProvider" type="MyNamespace.MyMembershipProvider" /> </providers></membership><!-- this role configuration below uses the SimpleRoleProvider, because I just wanted to replace the membership provider. If you need to replace that one too, just use your own class instead. --><roleManager enabled="true" defaultProvider="AspNetSqlRoleProvider"> <providers> <remove name="AspNetSqlRoleProvider" /> <add name="AspNetSqlRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <!-- note: WebMatrix registers SimpleRoleProvider with name 'AspNetSqlRoleProvider'. I don't know why but i kept it. --> </providers></roleManager>
I have checked the WebMatrix code, and it seems that setting 'enableSimpleMembership' to false is quite harmless. WebMatrix only uses it to initialize the membership/role providers (that can be substituted by the config above) and it enables the forms authentication allowing an alternative configuration way (through app settings) - this is also not necessary, if you have the standard forms authentication properly configured (mainly the 'loginUrl' is the only important player here).
I have also tried to check what the 'autoFormsAuthentication' setting does - but I haven't found anything, so just skipped it. Looks fine still.