asp.net 4.5 custom membership provider configuration throws strange exception
.net-4.5, asp.net, asp.net-mvc-4, visual-studio-2012
Solution
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.
Problem
My web site was initially written in MVC 4.0 RC using VS2010, . I have just downloaded and installed VS2012, and upgraded my project to Dotnet Framework 4.5. In my project I'm using a Custom MemberShipProvider and a custom RoleProvider. On VS2010 it worked like a charm. But now I'm keeping getting a strange Configuration Error: "This method cannot be called during the application's pre-start initialization phase." The "system.web -> membership -> providers -> add" line in my web.config is marked red as the source of the problem. I eliminated the suspicion that the problem has something to do with the migration process, by creating a new MVC 4.0 Project (in VS2012), adding my custom Membership/Role providers, changing the web.config appropriately, and finding that the error reappears! Digging deeper into the problem - I found the following information in the Application Log: Exception information: Exception type: InvalidOperationException Exception message: The pre-application start initialization method Start on type WebMatrix.WebData.PreApplicationStartCode threw an exception with the following error message: This method cannot be called during the application's pre-start initialization phase. (C:\Users\dov.AD\Documents\Visual Studio 2012\Projects\MvcApplication2\MvcApplication2\web.config line 52). at System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 methods, Func`1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) at System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath) at System.Web.Compilation.BuildManager.ExecutePreAppStart() at System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) This method cannot be called during the application's pre-start initialization phase. (C:\Users\dov.AD\Documents\Visual Studio 2012\Projects\MvcApplication2\MvcApplication2\web.config line 52) at System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase) at System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, Boolean checkAptcaBit, Boolean ignoreCase) at System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType) at System.Web.Configuration.ProvidersHelper.InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType) at System.Web.Security.Membership.InitializeSettings(Boolean initializeGeneralSettings, RuntimeConfig appConfig, MembershipSection settings) at System.Web.Security.Membership.Initialize() at System.Web.Security.Membership.get_Providers() at WebMatrix.WebData.WebSecurity.PreAppStartInit() at WebMatrix.WebData.PreApplicationStartCode.Start() This method cannot be called during the application's pre-start initialization phase. at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() at System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at System.Web.Configuration.ConfigUtil.GetType(String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase) ``` Request information: Request URL: http://localhost:4995/ Request path: / User host address: ::1 User: Is authenticated: False Authentication Type: Thread account name: AD\dov Thread information: Thread ID: 5 Thread account name: AD\dov Is impersonating: False Stack trace: at >System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 ``` methods, Func`1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods) at System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath) at System.Web.Compilation.BuildManager.ExecutePreAppStart() at System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) Please help, Thank you! Here is the web.config: ``` <?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MyWebSite-20120820105950;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MyWebSite-20120820105950.mdf" providerName="System.Data.SqlClient" /> <add name="MyWebSiteDbContext" providerName="System.Data.SqlClient" connectionString="server=.;database=MyWebSiteDB;Integrated Security=True;" /> </connectionStrings> <appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880" /> </authentication> <pages> <namespaces> <add namespace="System.Web.Helpers" /> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Optimization" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.WebPages" /> </namespaces> </pages> <profile> <providers> <clear/> </providers> </profile> <roleManager defaultProvider="MyWebSiteRoleProvider" enabled="true"> <providers> <clear/> <add name="MyWebSiteRoleProvider" type="MyWebSite.Security.MyWebSiteRoleProvider"/> </providers> </roleManager> <membership defaultProvider="MyWebSiteMembershipProvider"> <providers> <clear /> <add name="MyWebSiteMembershipProvider" type="MyWebSite.Security.MyWebSiteMembershipProvider" /> </providers> </membership> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /> <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> </entityFramework> </configuration> ``` This is the relevant custom membership (I have simplified it, but even though the problem is still there) code, only ValidateUser is really overridden: ``` using System; using System.Linq; using System.Web.Security; using DAL.MyWebSite; namespace MyWebSite.Security { public class MyWebSiteMembershipProvider : MembershipProvider { /// <summary> /// Verifies that the specified user name and password exist in the data source. /// </summary> /// <returns> /// true if the specified username and password are valid; otherwise, false. /// </returns> /// <param name="username">The name of the user to validate. </param><param name="password">The password for the specified user. </param> public override bool ValidateUser(string username, string password) { // simplified return true; } } } ``` This is the (simplified) RoleProvider: ``` using System; using System.Linq; using System.Web.Security; using DAL.MyWebSite; namespace MyWebSite.Security { public class MyWebSiteRoleProvider : RoleProvider { //readonly MyWebSiteDbContext _context = new MyWebSiteDbContext(); /// <summary> /// Gets a value indicating whether the specified user is in the specified role for the configured applicationName. /// </summary> /// <returns> /// true if the specified user is in the specified role for the configured applicationName; otherwise, false. /// </returns> /// <param name="username">The user name to search for.</param><param name="roleName">The role to search in.</param> public override bool IsUserInRole(string username, string roleName) { return true; //return GetRolesForUser(username).Contains(roleName); } /// <summary> /// Gets a list of the roles that a specified user is in for the configured applicationName. /// </summary> /// <returns> /// A string array containing the names of all the roles that the specified user is in for the configured applicationName. /// </returns> /// <param name="username">The user to return a list of roles for.</param> public override string[] GetRolesForUser(string username) { return new string[] {"one", "two"}; //var sm = _context.SalesManagers.Include("PermissionLevel").FirstOrDefault(manager => manager.UserName == username); //if (sm != null) //{ // if (sm.PermissionLevel.Name == "Sales Manager") // { // return new[] { "SalesManagers" }; // } // if (sm.PermissionLevel.Name == "Administrator") // { // return new[] { "SalesManagers", "Administrators" }; // } //} //return null; } } } ```