web-dev-qa-db-ja.com

asp.net 4.5カスタムメンバーシッププロバイダーの構成が奇妙な例外をスローする

私のWebサイトは当初、VS2010を使用してMVC 4.0 RCで作成されました。 VS2012をダウンロードしてインストールし、プロジェクトをDotnet Framework 4.5にアップグレードしました。

私のプロジェクトでは、カスタムMemberShipProviderとカスタムRoleProviderを使用しています。 VS2010では、それは魅力のように機能しました。しかし今、私は奇妙な構成エラーを取得し続けています:

「このメソッドは、アプリケーションの起動前初期化フェーズ中に呼び出すことはできません。」

Web.configの「system.web->メンバーシップ->プロバイダー->追加」行は、問題の原因として赤でマークされています。

新しいMVC 4.0プロジェクト(VS2012)を作成し、カスタムメンバーシップ/ロールプロバイダーを追加し、web.configを適切に変更し、エラーが再発することを見つけることで、問題が移行プロセスに関係しているという疑念を解消しました!

問題をより深く掘り下げる-アプリケーションログに次の情報が見つかりました。

例外情報:例外の種類:InvalidOperationException例外メッセージ:WebMatrix.WebData.PreApplicationStartCode型で開始するアプリケーション前の初期化メソッドStartは、次のエラーメッセージで例外をスローしました:このメソッドは、アプリケーションの開始前の初期化フェーズ中に呼び出すことはできません。 (C:\ Users\dov.AD\Documents\Visual Studio 2012\Projects\MvcApplication2\MvcApplication2\web.config line 52)。
System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection1 methods, Func1 setHostingEnvironmentCultures)at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods)at System.Web.Compilation.BuildManager.CallPreStartInitMethods System.Web.Hosting.HostingEnvironment.InitializeのSystem.Web.Compilation.BuildManager.ExecutePreAppStart()(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 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)System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings、Type providerType)at System.Web.Configuration.ProvidersHelper.InstantiateProviders(ProviderSettingsCollection configProviders、ProviderCollection provider、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.PreSecurityStartCode.Start()のWebMatrix.WebData.WebSecurity.PreAppStartInit()

このメソッドは、アプリケーションの起動前初期化フェーズ中に呼び出すことはできません。 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 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

メソッド、Func1 setHostingEnvironmentCultures) at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection 1メソッド)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)

助けてください、

ありがとうございました!

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;

        }

    }
}
30
berke762

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>

これで問題は解決しました。皆さんのお役に立てば幸いです。

70
Ben Pretorius

OK、この権利を説明できるかどうか見てみましょう。 ASP.NET 4では、新しいアセンブリレベルの属性PreApplicationStartMethodAttributeが導入されました。これは通常、_Properties/AssemblyInfo.cs_ファイルで使用されます。

ASP.NET MVC 4標準テンプレートには、_WebMatrix.WebData_アセンブリへの参照が付属しています。 そのコード を見ると、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)
    {
        ...
_

そのため、この「自動的に」失敗する方法/理由があります。 Microsoftが標準のWeb.configに_<add key="EnableSimpleMembershipKey" value="true" />_を含めず、「ここにセットアップされているSimpleProviderのものがある」ことをより明確にするのは本当に残念です。

24
Oli

私もこれを少し遊んで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」設定の機能を確認しようとしましたが、何も見つからなかったため、スキップしました。まだ元気そう。

8
Gaspar Nagy

私はすでに問題を解決しました。 VS2012でMVC 4プロジェクトを作成すると、テンプレートがいくつかのアセンブリへの参照を追加することがわかりました:webmatrixとOauth ...これらの参照を削除しただけで、問題はなくなりました。私はこれがどのように問題を解決したのか解りませんが、例外はWebMatrixアセンブリに由来することがわかりました。そのため、私はそれを削除しようとしました。申し訳ありませんが、調査に投資する時間はありません。

2
berke762