tutorial net for asp asp.net asp.net-mvc-4 visual-studio-2012 .net-4.5

asp.net - net - asp tutorial



La configuración del proveedor de membresía de asp.net 4.5 crea una extraña excepción (4)

Mi sitio web fue escrito inicialmente en MVC 4.0 RC usando VS2010,. Acabo de descargar e instalar VS2012, y actualicé mi proyecto a Dotnet Framework 4.5.

En mi proyecto estoy usando un MemberShipProvider personalizado y un RoleProvider personalizado. En VS2010 funcionó a las mil maravillas. Pero ahora sigo obteniendo un extraño error de configuración:

"Este método no se puede llamar durante la fase de inicialización previa al inicio de la aplicación".

La línea "system.web -> membership -> providers -> add" en mi web.config se marca en rojo como origen del problema.

Eliminé la sospecha de que el problema tiene algo que ver con el proceso de migración, al crear un nuevo Proyecto MVC 4.0 (en VS2012), agregar mis proveedores de Membresía / Función personalizados, cambiar el web.config de manera apropiada y encontrar que el error vuelve a aparecer.

Profundizando en el problema: encontré la siguiente información en el Registro de la aplicación:

Información de excepción: Tipo de excepción: InvalidOperationException Mensaje de excepción: el método de inicialización de inicio de la preinstalación Start on type WebMatrix.WebData.PreApplicationStartCode lanzó una excepción con el siguiente mensaje de error: No se puede llamar a este método durante la fase de inicialización previa a la aplicación. (C: / Users / dov.AD / Documents / Visual Studio 2012 / Projects / MvcApplication2 / MvcApplication2 / web.config línea 52).
en System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore ( 1 methods, Func ICollection 1 methods, Func 1 setHostingEnvironmentCultures) en System.Web.Compilation.BuildManager.InvokePreStartInitMethods (métodos ICollection`1) en System.Web.Compilation.BuildManager.CallPreStartInitMethods (String preStartInitListPath) en System.Web.Compilation.BuildManager.ExecutePreAppStart () en System.Web.Hosting.HostingEnvironment.Initialize (ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException)

Este método no puede invocarse durante la fase de inicialización previa al inicio de la aplicación. (C: / Users / dov.AD / Documents / Visual Studio 2012 / Projects / MvcApplication2 / MvcApplication2 / web.config línea 52)
en System.Web.Configuration.ConfigUtil.GetType (String typeName, String propertyName, ConfigurationElement configElement, XmlNode node, Boolean checkAptcaBit, Boolean ignoreCase) en System.Web.Configuration.ConfigUtil.GetType (String typeName, String propertyName, ConfigurationElement configElement, Boolean checkAptcaBit, Boolean ignoreCase) en System.Web.Configuration.ProvidersHelper.InstantiateProvider (ProviderSettings providerSettings, Type providerType) en System.Web.Configuration.ProvidersHelper.InstantiateProviders (ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType)
en System.Web.Security.Membership.InitializeSettings (Boolean initializeGeneralSettings, RuntimeConfig appConfig, configuración de MembershipSection) en System.Web.Security.Membership.Initialize () en System.Web.Security.Membership.get_Providers () en WebMatrix.WebData.WebSecurity .PreAppStartInit () en WebMatrix.WebData.PreApplicationStartCode.Start ()

Este método no puede invocarse durante la fase de inicialización previa al inicio de la aplicación. en System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled ()
en System.Web.Compilation.BuildManager.GetType (String typeName, Boolean throwOnError, Boolean ignoreCase) en System.Web.Configuration.ConfigUtil.GetType (String typeName, String propertyName, ConfigurationElement configElement, nodo XmlNode, 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

métodos, Func 1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection métodos 1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection 1) en System.Web.Compilation.BuildManager.CallPreStartInitMethods (String preStartInitListPath) en System.Web.Compilation.BuildManager.ExecutePreAppStart () en System. Web.Hosting.HostingEnvironment.Initialize (ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException)

Por favor ayuda,

¡Gracias!

Aquí está el 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>

Este es el código de membresía personalizado relevante (lo he simplificado, pero aunque el problema todavía está allí), solo ValidateUser está anulado:

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

Este es el RoleProvider (simplificado):

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


OK veamos si puedo explicar esto bien. ASP.NET 4 introdujo un nuevo atributo de nivel de ensamblaje: PreApplicationStartMethodAttribute , que normalmente se utiliza en el archivo Properties/AssemblyInfo.cs .

La plantilla estándar ASP.NET MVC 4 viene con una referencia al ensamblado WebMatrix.WebData . Al mirar su código , AssemblyInfo tiene esto:

[assembly: PreApplicationStartMethod(typeof(PreApplicationStartCode), "Start")]

Entonces, básicamente, antes de invocar App_Start, el framework llamará a WebMatrix.WebData.PreApplicationStartCode.Start() que, entre otras cosas, hace esto

// Initialize membership provider WebSecurity.PreAppStartInit();

Y por supuesto, como dijo @Ben Pretorius, ese método comienza así

internal static void PreAppStartInit() { // Allow use of <add key="EnableSimpleMembershipKey" value="false" /> to disable registration of membership/role providers as default. if (ConfigUtil.SimpleMembershipEnabled) { ...

Así que allí tienes cómo / por qué este "automáticamente" falla. Es una lástima que Microsoft no haya incluido <add key="EnableSimpleMembershipKey" value="true" /> en el Web.config estándar para hacerlo más obvio que "hey there''s this SimpleProvider cosas que está configurado aquí".


También estaba jugando un poco a esto y buscando en el código de WebMatrix y, finalmente, creo que la solución de Ben parece ser la de trabajo.

(También he intentado jugar con las referencias de ensamblado sin éxito. Creo que al eliminar las referencias que acaba de lograr, al igual que las configuraciones de configuración, la seguridad de WebMatrix no se inicializó correctamente. Pero creo que es una forma bastante peligrosa. Solo estoy adivinando aquí.)

Entonces para mí lo que funcionó:

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

He comprobado el código de WebMatrix, y parece que establecer ''enableSimpleMembership'' en false es bastante inofensivo. WebMatrix solo lo usa para inicializar los proveedores de membresía / función (que pueden ser sustituidos por la configuración anterior) y habilita la autenticación de formularios permitiendo una configuración alternativa (a través de la configuración de la aplicación); esto tampoco es necesario, si tiene los formularios estándar autenticación configurada correctamente (principalmente el ''loginUrl'' es el único jugador importante aquí).

También intenté comprobar qué hace la configuración ''autoFormsAuthentication'', pero no encontré nada, así que me salté. Se ve bien todavía.


Utilizo mis propios proveedores de Membresía y Roles personalizados desde MVC2 y me encontré con este problema cuando migré de MVC3 a 4.

Creé un nuevo proyecto en MVC4 / .net4.5 EF5 y tuve la oportunidad de encontrar este error.

Logré solucionarlo haciendo lo siguiente:

Agregue esto a sus appsettings de webconfig:

<appSettings> <add key="enableSimpleMembership" value="false"/> <add key="autoFormsAuthentication" value="false"/> </appSettings>

Agregue su cadena de conexión a sus proveedores de membresías y roles si aún no está configurado:

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

Esto resolvió el problema para mí y espero que pueda ayudarte.


Ya resolví el problema. Descubrí que al crear el proyecto MVC 4 en VS2012, la plantilla agrega referencias a algunos ensambles, entre ellos: webmatrix y Oauth ... Acabo de eliminar esas referencias, y el problema desapareció. No sé para responder cómo esto resolvió el problema, pero vi que la excepción proviene del ensamblaje de WebMatrix, así que por esa razón traté de eliminarlo. Lo siento, pero no tengo tiempo para invertir en investigación ...