【问题标题】:asp.net 4.5 custom membership provider configuration throws strange exception [duplicate]asp.net 4.5 自定义会员提供程序配置抛出奇怪的异常 [重复]
【发布时间】:2012-10-25 22:09:39
【问题描述】:

我的网站最初是使用 VS2010 用 MVC 4.0 RC 编写的,. 我刚刚下载并安装了VS2012,并将我的项目升级到Dotnet Framework 4.5。

在我的项目中,我使用了自定义 MemberShipProvider 和自定义 RoleProvider。在 VS2010 上,它就像一个魅力。但现在我不断收到一个奇怪的配置错误:

“在应用程序的预启动初始化阶段不能调用此方法。”

我的 web.config 中的“system.web -> members -> providers -> add”行被标记为红色作为问题的根源。

我消除了问题与迁移过程有关的怀疑,方法是创建一个新的 MVC 4.0 项目(在 VS2012 中),添加我的自定义成员/角色提供程序,适当地更改 web.config,并发现错误再次出现!

深入研究问题 - 我在应用程序日志中发现了以下信息:

异常信息: 异常类型:InvalidOperationException 异常消息:WebMatrix.WebData.PreApplicationStartCode 类型的预应用程序启动初始化方法 Start 引发了 带有以下错误消息的异常:此方法不能 在应用程序的预启动初始化阶段调用。 (C:\Users\dov.AD\Documents\Visual Studio 2012\Projects\MvcApplication2\MvcApplication2\web.config 第 52 行)。
在 System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection1 methods, Func1 setHostingEnvironmentCultures) 在 System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 方法)在 System.Web.Compilation.BuildManager.CallPreStartInitMethods(字符串 preStartInitListPath) 在 System.Web.Compilation.BuildManager.ExecutePreAppStart() 在 System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, 异常 appDomainCreationException)

在应用预启动期间不能调用该方法 初始化阶段。 (C:\Users\dov.AD\Documents\Visual Studio 2012\Projects\MvcApplication2\MvcApplication2\web.config 第 52 行)
在 System.Web.Configuration.ConfigUtil.GetType(字符串类型名,字符串 propertyName、ConfigurationElement configElement、XmlNode 节点、 Boolean checkAptcaBit, Boolean ignoreCase) 在 System.Web.Configuration.ConfigUtil.GetType(字符串类型名,字符串 propertyName, ConfigurationElement configElement, Boolean checkAptcaBit,布尔忽略大小写)在 System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings,类型 providerType) 在 System.Web.Configuration.ProvidersHelper.InstantiateProviders(ProviderSettingsCollection configProviders、ProviderCollection 提供者、类型 providerType)
在 System.Web.Security.Membership.InitializeSettings(布尔 初始化GeneralSettings、RuntimeConfig appConfig、MembershipSection 设置)在 System.Web.Security.Membership.Initialize() 在 System.Web.Security.Membership.get_Providers() 在 WebMatrix.WebData.WebSecurity.PreAppStartInit() 在 WebMatrix.WebData.PreApplicationStartCode.Start()

在应用预启动期间不能调用该方法 初始化阶段。在 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
在 System.Web.Compilation.BuildManager.GetType(字符串类型名称, Boolean throwOnError, Boolean ignoreCase) 在 System.Web.Configuration.ConfigUtil.GetType(字符串类型名,字符串 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

方法,Func1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection1 方法)在 System.Web.Compilation.BuildManager.CallPreStartInitMethods(字符串 preStartInitListPath) 在 System.Web.Compilation.BuildManager.ExecutePreAppStart() 在 System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, 异常 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;

        }

    }
}

【问题讨论】:

  • 为了简单起见和消息长度限制,我在此处粘贴了我的提供程序的缩短版本,并确保配置问题仍然存在。
  • 我觉得配置代码比较重要。

标签: asp.net asp.net-mvc-4 visual-studio-2012 .net-4.5


【解决方案1】:

我在自 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>

这解决了我的问题,我希望它可以帮助你。

【讨论】:

  • 本,谢谢你的回答。事实上,在我在这里发布我的问题之前,我在其他论坛上看到了答案。我不想尝试它,因为它会更改我的 Web 项目中的设置,并且我希望它能够像在 VS2010 SP1 中一样工作。另外,正如我在问题中所写,我的项目最初是用 MVC 4 (RC) 编写的,所以恕我直言,这个答案似乎不适合我所面临的情况。请看我刚刚发布的答案...
  • 感谢您的反馈。我会试试这个,因为它看起来确实比更新配置更好!
  • 我玩过这个解决方案。请在单独的答案中查看我的发现(太长,无法在此处粘贴)
  • 如果您使用 MVC4,请将 enabled 属性添加到您的 Web 配置中,以便它使用 RolePrincipal。 如果您不添加它,那么它将默认为您的身份验证属性中的 GenericPrincipal 并且永远不会命中您的自定义角色提供程序。
【解决方案2】:

好的,让我们看看我是否可以正确解释这一点。 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 中包含 &lt;add key="EnableSimpleMembershipKey" value="true" /&gt; 实在太糟糕了,以使“嘿,这里设置了这个 SimpleProvider 的东西”更加明显。

【讨论】:

  • 感谢您的回答。它揭示了这个谜团。
  • @berke762 确实如此,不是吗?那你为什么不接受它作为答案呢? Oli 和 Ben Pretorius 都提供了有效的答案,我只是尝试了一下(与自定义提供程序有同样的问题)。
  • 我认为在最近的软件包更新中这已更改为使用 InitializeSimpleMembershipAttributeJon Galloways article 也提供了很多关于这个主题的信息。
  • 我宁愿摆脱未使用的程序集,而不是设置密钥。如果您不使用它们,为什么还要在您的项目中使用它们?您可以手动删除 WebMatrix 程序集,也可以只删除 Microsoft.AspNet.WebpPages.WebDataMicrosoft.AspNet.WebpPages.Data 包。
【解决方案3】:

我也在玩这个,研究 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' 设置的作用 - 但我没有找到任何东西,所以跳过它。看起来还不错。

【讨论】:

  • 这对我有用。谢谢。
【解决方案4】:

我已经解决了这个问题。我发现当你在 VS2012 中创建 MVC 4 项目时,模板添加了对一些程序集的引用,其中:webmatrix 和 Oauth... 我刚刚删除了这些引用,问题就消失了。我不知道这是如何解决问题的,但我看到异常来自 WebMatrix 程序集,因此我试图将其删除。抱歉,我没时间投入调查……

【讨论】:

  • 当然它来自 WebMatrix 程序集,这就是 Simple Membership 实现的地方,它被引入 MVC4,这就是为什么在 web.config 中禁用 Simple Membership 的原因。只需接受上述答案之一即可。
  • adamsın berke çok sağol
猜你喜欢
  • 1970-01-01
  • 2011-11-27
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多