我的网站最初是使用VS2010在MVC 4.0 RC中编写的。 我刚下载并安装了VS2012,并将我的项目升级到Dotnet Framework 4.5。
在我的项目中,我正在使用Custom MemberShipProvider和自定义RoleProvider。在VS2010上,它就像一个魅力。但现在我一直在收到一个奇怪的配置错误:
“在应用程序的预启动初始化阶段,无法调用此方法。”
我的web.config中的“system.web - >成员资格 - >提供商 - >添加”行标记为红色,作为问题的根源。
我通过创建一个新的MVC 4.0项目(在VS2012中),添加我的自定义成员资格/角色提供程序,适当地更改web.config以及发现该问题,消除了对该问题与迁移过程有关的怀疑。错误再次出现!
深入研究问题 - 我在应用程序日志中找到了以下信息:
异常信息: 异常类型:InvalidOperationException 异常消息:预应用程序启动初始化方法启动类型WebMatrix.WebData.PreApplicationStartCode抛出一个 异常,出现以下错误消息:此方法不能 在应用程序的预启动初始化阶段调用。 (C:\ Users \ dov.AD \ Documents \ Visual Studio 2012 \ Projects \ MvcApplication2 \ MvcApplication2 \ web.config第52行。) 在 System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection
1 methods, Func
1 setHostingEnvironmentCultures)at at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 方法) System.Web.Compilation.BuildManager.CallPreStartInitMethods(字符串 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)在应用程序的预启动期间无法调用此方法 初始化阶段。 (C:\ Users \ dov.AD \ Documents \ Visual Studio 2012 \ Projects \ MvcApplication2 \ MvcApplication2 \ web.config第52行)
在System.Web.Configuration.ConfigUtil.GetType(String typeName,String propertyName,ConfigurationElement configElement,XmlNode节点, 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)
在System.Web.Security.Membership.InitializeSettings(布尔值 initializeGeneralSettings,RuntimeConfig appConfig,MembershipSection 设置)在System.Web.Security.Membership.Initialize()at System.Web.Security.Membership.get_Providers()at WebMatrix.WebData.WebSecurity.PreAppStartInit()at WebMatrix.WebData.PreApplicationStartCode.Start()在应用程序的预启动期间无法调用此方法 初始化阶段。在 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
在System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError,Boolean ignoreCase)at System.Web.Configuration.ConfigUtil.GetType(String typeName,String propertyName,ConfigurationElement configElement,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
方法,Func
1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection
1 方法) System.Web.Compilation.BuildManager.CallPreStartInitMethods(字符串 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)
请帮忙,
谢谢!
这是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>
这是相关的自定义成员资格(我已将其简化,但即使问题仍然存在)代码,只有ValidateUser才被覆盖:
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;
}
}
}
这是(简化的)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;
}
}
}
答案 0 :(得分:70)
我在自MVC2中使用自己的自定义成员资格和角色提供程序,并在从MVC3迁移到4时遇到此问题。
我在MVC4 / .net4.5 EF5中创建了一个新项目,并且遇到了这个错误。
我设法通过执行以下操作来修复它:
将此添加到您的webconfig appsettings:
<appSettings>
<add key="enableSimpleMembership" value="false"/>
<add key="autoFormsAuthentication" value="false"/>
</appSettings>
如果尚未设置,请将您的连接字符串添加到您的成员资格和角色提供者:
<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>
这解决了我的问题,我希望它可以帮到你。
答案 1 :(得分:24)
好的,让我们看看我是否可以解释这一点。 ASP.NET 4引入了一个新的程序集级属性:PreApplicationStartMethodAttribute
,通常在Properties/AssemblyInfo.cs
文件中使用。
ASP.NET MVC 4标准模板附带对WebMatrix.WebData
程序集的引用。查看its code,AssemblyInfo确实有这个:
[assembly: PreApplicationStartMethod(typeof(PreApplicationStartCode), "Start")]
所以基本上,在调用App_Start之前,框架将调用WebMatrix.WebData.PreApplicationStartCode.Start()
,除其他外,它会执行此操作
// Initialize membership provider
WebSecurity.PreAppStartInit();
果然,就像@Ben Pretorius所说,这种方法就像这样开始
internal static void PreAppStartInit()
{
// Allow use of <add key="EnableSimpleMembershipKey" value="false" /> to disable registration of membership/role providers as default.
if (ConfigUtil.SimpleMembershipEnabled)
{
...
所以你有这个“自动”失败的方式/原因。微软没有在标准的Web.config中包含<add key="EnableSimpleMembershipKey" value="true" />
以使其更加明显“嘿,这里有设置的SimpleProvider东西”,这真的太糟糕了。
答案 2 :(得分:8)
我也在讨论这个问题并查看WebMatrix代码,最后我认为Ben的解决方案似乎是有效的。
(我也尝试过使用程序集引用而没有成功。我认为删除你刚刚实现的配置与配置设置相同 - WebMatrix安全性没有正确初始化。但我认为这是非常危险的但是我只是在这里猜测。)
所以对我来说有用:
<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>
我检查了WebMatrix代码,似乎将'enableSimpleMembership'设置为false是非常无害的。 WebMatrix仅使用它来初始化成员资格/角色提供者(可以由上面的配置代替),并且它允许表单身份验证允许替代配置方式(通过应用程序设置) - 如果您有标准表单,这也没有必要验证配置正确(主要是'loginUrl'是这里唯一重要的播放器)。
我还尝试检查'autoFormsAuthentication'设置的作用 - 但我没有找到任何内容,所以只是跳过它。看起来还不错。
答案 3 :(得分:2)
我已经解决了这个问题。我发现在VS2012中创建MVC 4项目时,模板会添加对某些程序集的引用,其中包括:webmatrix和Oauth ...... 我刚刚删除了这些引用,问题就消失了。我不知道如何解决这个问题,但我看到Exception来自WebMatrix程序集,因此我试图删除它。对不起,我没有时间投资调查......