2

私は問題で本当に苦労しています。エンティティ保存パイプラインにフックするために使用できるカスタム アセンブリを顧客が提供できるように、変更したばかりの Web アプリケーションがあります。これらのカスタム アセンブリは、エンティティがデータベースに永続化されるときに、リフレクションを介して読み込まれます。これらは、すべてのデータ アクセスを処理する共通の DAL アセンブリを参照します。

このシステムが問題なく動作するテスト サーバー (Win2k3) があります。これを運用サーバー クラスター (1 つの Win2k3 と 1 つの Win2k8) にプッシュしたので、カスタム アセンブリは、データベース (SQL2005) にアクセスする DAL メソッドを初めて呼び出すときに爆発します。収集したログ情報は、SqlClientPermission の取得に失敗したことを示しています。ベスト プラクティスに反して、Web アプリを完全信頼で実行しています。カスタム アセンブリに厳密な名前が付けられています。

テスト サーバーの構成と実稼働サーバーの構成の違いをどこで探すことができるかについての提案はありますか? これが適切なフォーラムでない場合、どのフォーラムですか?

ありがとう、マシュー

4

3 に答える 3

1

私は反射なしで同様の問題に遭遇していました。コンパイル済みのプロジェクトを Win 2k3 マシンから Win 2k8 に移動していました。- IIS で、dll がある bin フォルダーの下に移動し、右クリックします。- 「権限の編集...」に移動します。- [一般] タブの一番下に、[ブロック解除] というボタンがある場合があります。

Win 2k8 は、別の環境からコピーされた dll を好まないようです。

于 2010-08-24T12:42:22.870 に答える
0

爆撃する反射オブジェクトのメソッドは次のとおりです。

    public EntityBase2 AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
    {
        SurveyResponseEntity response = entity as SurveyResponseEntity;

        if (response.IsComplete) // we only really want to do this if the survey has been completed.
        {
            SurveyEntity survey = new SurveyEntity(response.SurveyRefId);
            IPrefetchPath2 questionSetPath = new PrefetchPath2((int)SS2DAL.EntityType.SurveyEntity);
            IPredicateExpression filter = new PredicateExpression(QuestionSetFields.Current == 1);
            questionSetPath.Add(SurveyEntity.PrefetchPathQuestionSetCollection, 1, filter)
                .SubPath.Add(QuestionSetEntity.PrefetchPathQuestionPageCollection)
                    .SubPath.Add(QuestionPageEntity.PrefetchPathQuestionCollection);

            if (adapter.FetchEntity(survey, questionSetPath))
            {
                // we need to instantiate the survey template save handler from this survey response (if it exists)
                // then execute

                if (!String.IsNullOrEmpty(survey.PostSaveAssemblyName) && !String.IsNullOrEmpty(survey.PostSaveClassName))
                {
                    try
                    {
                        string assemblyPath = (new FileService()).GetRootAssemblyURL();

                        Assembly asm = Assembly.Load(File.ReadAllBytes(Path.Combine(assemblyPath, survey.PostSaveAssemblyName)));

                        if (asm != null)
                        {
                            Type t = asm.GetType(survey.PostSaveClassName);
                            ISurveyPostSaveHandler cls = (ISurveyPostSaveHandler)Activator.CreateInstance(t);
                            if (cls != null)
                            {
                                cls.AfterSave(response, survey, adapter);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // at some point, we need to add some logging here.
                        Logger.ErrorFormat("There was an error post-processing survey response {0} from survey {1}: {2}", response.SurveyResponseId, survey.Name, ex.ToString());
                        throw ex;
                    }
                }
            }
            else
            {
                Logger.ErrorFormat("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId);
                throw new ApplicationException(String.Format("Could not post process response {0} because the parent survey could not be located", response.SurveyResponseId));
            }
        }

        return response;
    }

    #endregion
}
于 2009-07-31T19:51:20.383 に答える
0

答えではありませんが、コメントに入れるよりも多くの情報...

クラスター内の Win2k3 サーバーからのログに例外が記録されなくなったため、これは Win2k8 と Win2k3 の問題であると思われます。

基本的に、エンティティ保存パイプラインは、保存されるエンティティ タイプが特定のインターフェイスを実装しているかどうかを確認します。その場合、アプリケーションはデータベースにアクセスして、顧客固有の保存前および保存後の機能を実装するクラスのアセンブリとクラス名を取得します。これらのアセンブリは、"Assemblies\" というフォルダー内の "App_Data" フォルダーの下にあります。次に、アプリケーションはアセンブリを読み込みます。リフレクションを使用して、そのアセンブリから適切なクラスをインターフェイスとしてインスタンス化し、そのインターフェイスで事前および事後保存メソッドを呼び出して、その特定のエンティティ タイプに対して顧客固有のアクションを実行します。この場合、このカスタム アクションは、DAL (LLBLGen、FWIW を使用) エンティティ クラスを使用していくつかのデータベース操作を実行します。

私の最初の問題は、部分的に信頼された呼び出し元を許可しないことに関する SecurityException を取得していたことでした。そのため、"AllowPartiallyTrustedCallers" 属性で使用されるアセンブリを装飾しました。

ロードされる拡張機能アセンブリで、SqlClientPermission をインスタンス化し、それを「Assert()」しますが、実際にはそのアクセス許可をどこにも付与していません (Web アプリが FullTrust で実行されている場合を除く)。

あなたが提供できるどんな助けにも感謝します...

-マシュー

スローされる例外の .ToString() 出力は次のとおりです。

Error performing post-save operation on entity 373c595e-843b-45a1-82d0-aa166daf75de of type SS2DAL.EntityClasses.SurveyResponseEntity: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException: An exception was caught during the execution of a retrieval query: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception. ---> System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
   at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessPermission.Demand()
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Data.SqlClient.SqlClientPermission
The first permission that failed was:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The demand was for:
<IPermission
version="1"
AllowBlankPassword="False">
<add KeyRestrictions=""
KeyRestrictionBehavior="AllowOnly"/>
</IPermission>

The granted set of the failing assembly was:
<PermissionSet
version="1">
<IPermission
version="1"
Access="Open"/>
<IPermission
version="1"
Allowed="ApplicationIsolationByUser"
UserQuota="512000"/>
<IPermission
version="1"
Flags="Execution"/>
<IPermission
version="1"
Window="SafeTopLevelWindows"
Clipboard="OwnClipboard"/>
<IPermission
version="1"
PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100B55C03865E07BCB230B04EF7D9ACF1E7BF41C618DB1327895C25328446039F51CF237A50989E542D3FA9BB5991D303388C5AAC7AE4E071CD7B42B96B16256FF905EC610107DB2A0872E971253919BA528187489FC89FD083118F562319BF3B66CB79035EC50D2291561D4F2B9733AD5E0ECD9BFF9B80B94C40F5888D4E1C5BDD"
Name="ProjectHelpers.Extensions"
AssemblyVersion="2.2009.208.1821"/>
<IPermission
version="1"
Url="file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll"/>
<IPermission
version="1"
Zone="Internet"/>
<IPermission
version="1"
Level="SafePrinting"/>
</PermissionSet>

The assembly or AppDomain that failed was:
ProjectHelpers.Extensions, Version=2.2009.208.1821, Culture=neutral, PublicKeyToken=4405fd38c7d52787
The method that caused the failure was:
SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2 AfterSave(SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2, SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase)
The Zone of the assembly that failed was:
Internet
The Url of the assembly that failed was:
file://dc01.bizspeed.datacenter/websites/sitesupervisor files/prjh/ProjectHelpers.Extensions.dll
   --- End of inner exception stack trace ---
   at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteSingleRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFields2 fieldsToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfos, IRelationPredicateBucket filter)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityUsingFilter(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, IRelationPredicateBucket filter, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath, Context contextToUse, ExcludeIncludeFieldsList excludedIncludedFields)
   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntity(IEntity2 entityToFetch, IPrefetchPath2 prefetchPath)
   at ProjectHelpers.Extensions.SurveyResponseSaveHelper.AfterSave(EntityBase2 entity, DataAccessAdapterBase adapter)
   at SS2.RemoteObjects.DataPortal.EntitySaveWithoutRemoting(EntityBase2 entity, AuditSettings auditSettings, AuthTicket at)  [NDC:(null)]
于 2009-07-31T19:46:00.003 に答える