次の方法で共有


Dataverse プラグインのトラブルシューティング

この記事では、プラグインの実行中に発生する可能性があるエラー、またはプラグインに関連する Dataverse エラー、およびそれらを回避または修正する方法について説明します。

エラー "時間変換を完了できませんでした"

エラー コード: -2147220956
エラー メッセージ: 指定された DataTime に Kind プロパティが正しく設定されていないため、変換を完了できませんでした。 たとえば、Kind プロパティが DateTimeKind.Local の場合、ソース タイム ゾーンは TimeZoneInfo.Local である必要があります。

このエラーは、プラグイン コードの呼び出し中 TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) に発生し、サンティアゴまたは Volgograd タイム ゾーンの値を協定世界時 (UTC) に変換 DateTime する場合があります。

このエラーは既知の製品制限が原因で発生し、現在のところ回避策はありません。

詳細については、「 ユーザーのタイム ゾーン設定を指定する」を参照してください。

エラー "サンドボックス ワーカー プロセスがクラッシュしました"

エラー コード: -2147204723
エラー メッセージ: サンドボックス ワーカー プロセスがクラッシュしたため、プラグインの実行が失敗しました。 これは通常、プラグイン コードのエラーが原因です。

このエラーは、プラグイン コードを実行しているワーカー プロセスがクラッシュしたことを意味します。 プラグインがクラッシュの原因である可能性がありますが、organizationで同時に実行されている別のプラグインである可能性もあります。 プロセスがクラッシュしたため、クラッシュした理由に関するより具体的な情報を抽出することはできません。 しかし、事後のクラッシュ ダンプからのデータを調べた結果、このエラーは通常、次の 4 つの理由のいずれかが原因で発生することがわかりました。

プラグインの未処理の例外

プラグインを記述するときは、失敗する可能性のある操作を予測し、try-catch ブロックにラップする必要があります。 エラーが発生した場合は、 クラスを InvalidPluginExecutionException 使用して、ユーザーにとって意味のあるエラーで操作を正常に終了する必要があります。

詳細については、「 プラグインでの例外の処理」を参照してください。

この例外の一般的なシナリオは、 HttpClient.SendAsync メソッドまたは HttpClient.GetAsync メソッドを使用する場合です。 これらの HttpClient メソッドは、 Task を返す非同期操作です。 コードを同期する必要があるプラグインで作業するには、 タスク<TResult> を使用する可能性があります。Result プロパティ。 エラーが発生した場合は、 ResultAggregateException を返します。 では AggregateException 、複数のエラーが 1 つの例外に統合されます。これは処理が困難な場合があります。 より優れた設計は、 Task<TResult を使用することです>。GetAwaiter().GetResult() は、エラーの原因となった特定のエラーとして結果を伝達するためです。

次の例は、 HttpClient.GetAsync メソッドを使用して例外と送信呼び出しを管理する正しい方法を示しています。 このプラグインは、登録されたステップの安全でない構成で Uri セットの応答テキストを取得しようとします。

using Microsoft.Xrm.Sdk;
using System;
using System.Net.Http;

namespace ErrorRepro
{
    public class AsyncError : IPlugin
    {
        private readonly string webAddress;

        public AsyncError(string unsecureConfig)
        {
            if (string.IsNullOrEmpty(unsecureConfig)) {
                throw new InvalidPluginExecutionException("The ErrorRepro.AsyncError plug-in requires that a Url be set in the unsecure configuration for the step registration.");
            }
            webAddress = unsecureConfig;

        }

        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
            (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.AsyncError");
            tracingService.Trace($"Sending web request to {webAddress}");

            try
            {
                string responseText = GetWebResponse(webAddress, tracingService);
                tracingService.Trace($"Result: {responseText.Substring(0, 100)}");
            }
            catch (Exception ex)
            {
                tracingService.Trace($"Error: ErrorRepro.AsyncError {ex.Message}");
                throw new InvalidPluginExecutionException(ex.Message);
            }
            tracingService.Trace($"Ending ErrorRepro.AsyncError");
        }

        //Gets the text response of an outbound web service call
        public string GetWebResponse(string webAddress, ITracingService tracingService)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
                    client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false

                    HttpResponseMessage response = client.GetAsync(webAddress).GetAwaiter().GetResult(); //Make sure it is synchronous
                    response.EnsureSuccessStatusCode();

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse succeeded.");

                    string responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //Make sure it is synchronous

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse responseContent parsed successfully.");

                    return responseContent;

                }
            }
            catch (Exception ex)
            {
                //Capture the inner exception message if it exists.
                // It should have a more specific detail.
                string innerExceptionMessage = string.Empty;
                if (ex.InnerException != null) {
                    innerExceptionMessage = ex.InnerException.Message;
                }

                tracingService.Trace($"Error in ErrorRepro.AsyncError : {ex.Message} InnerException: {innerExceptionMessage}");
                if (!string.IsNullOrEmpty(innerExceptionMessage))
                {
                    throw new Exception($"A call to an external web service failed. {innerExceptionMessage}", ex);
                }

                throw new Exception("A call to an external web service failed.", ex);
            }
        }
    }
}

スレッドを使用してキューに入れ、スレッド デリゲートで try/catch なしで作業を行う

プラグインでは並列実行パターンを使用しないでください。このアンチパターンは、ベスト プラクティスに関する記事で呼び出されています。 プラグインとワークフロー アクティビティ内で並列実行を使用しないでください。 これらのパターンを使用すると、同期プラグインでのトランザクションの管理に問題が発生する可能性があります。 ただし、これらのパターンを使用しないもう 1 つの理由は、スレッド デリゲートのブロックの try/catch 外部で実行された作業がワーカー プロセスをクラッシュさせる可能性があるということです。

重要

ワーカー プロセスがクラッシュすると、そのプロセスで現在実行されているプラグインやその他のプラグインの実行が終了します。 これには、所有または保守していないプラグインが含まれます。

Application Insights to the rescue

以前は、クラッシュしたワーカー プロセスからハンドルされないプラグイン例外のスタック トレースやその他の実行情報を取得することは不可能でした。 ただし、Dataverse では、Application Insights への実行エラーのログ記録がサポートされるようになりました。 この関数を有効にするには、Application Insights をプラグインが登録されている環境にリンクできます。 リンクすると、プラグインのクラッシュのログが自動的に発生します。

詳細については、「 Application Insights へのデータのエクスポート」を参照してください。

Application Insights 環境がリンクされると、次の作業プロセス クラッシュデータが問題のトラブルシューティングに使用できるようになります。

Application Insights プラグインのクラッシュ レポートの例。

Application Insights のクラッシュ レポートに移動するには、次の手順に従います。

  1. Application Insights を環境にリンクします
  2. プラグイン例外によってワーカー プロセスのクラッシュ エラーが発生するまで待ちます。
  3. Power Platform 管理センターで、Application Insights に移動します。
  4. [Application Insights] ページで、左側のパネルで [エラー ] を選択します。
  5. [失敗] ページ 、[例外] を選択 します
  6. [ 例外の問題 ID] の [全体 ] の一覧で、[ Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException] を選択します。
  7. ページの右側にある [ 全体] で、[ PluginWorkerCrashException] を選択します。 記録されたすべてのワーカー プロセスクラッシュ例外の詳細が表示されます。
  8. Searchして左側のパネルで目的の例外を選択すると、例外の詳細レポートがページの右側に表示されます (例については、前のスクリーンショットを参照してください)。
  9. スタック トレースにアクセスするには、レポートで CrashDetails を展開します。

プラグインのスタック オーバーフロー エラー

この種類のエラーは、プラグイン コードを変更した直後に最も頻繁に発生します。 一部のユーザーは、独自の基本クラスのセットを使用して、開発エクスペリエンスを合理化します。 これらのエラーは、特定のプラグインが依存する基底クラスへの変更から発生する場合があります。

たとえば、終了条件のない再帰呼び出しや、すべてのシナリオに対応していない終了条件は、このエラーを発生させる可能性があります。 詳細については、「 StackOverflowException クラス > の備考」を参照してください。

プラグインに対して最近適用されたコードの変更と、プラグイン コードが依存するその他のコードを確認する必要があります。

次のプラグイン コードでは、 StackOverflowException 制限のない再帰呼び出しが原因で が発生します。 トレースを使用してエラーをキャプチャしようとしたにもかかわらず、トレースとエラーは返されません。これは、処理するワーカー プロセスが終了したためです。

using Microsoft.Xrm.Sdk;
using System;

namespace ErrorRepro
{
    public class SOError : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
           (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.SOError");

            try
            {
                tracingService.Trace($"Calling RecursiveMethodWithNoLimit to trigger StackOverflow error.");

                RecursiveMethodWithNoLimit(tracingService); //StackOverflowException occurs here.
            }
            catch (Exception ex)
            {
                //This trace will not be written
                tracingService.Trace($"Error in ErrorRepro.SOError {ex.Message}");

                //This error will never be thrown
                throw new InvalidPluginExecutionException($"Error in ErrorRepro.SOError. {ex.Message}");
            }

            //This trace will never be written
            tracingService.Trace($"Ending ErrorRepro.SOError");
        }

        public static void RecursiveMethodWithNoLimit(ITracingService tracingService)
        {
            tracingService.Trace($"Starting ErrorRepro.SOError.RecursiveMethodWithNoLimit");

            RecursiveMethodWithNoLimit(tracingService);

            tracingService.Trace($"Ending ErrorRepro.SOError.RecursiveMethodWithNoLimit");
        }
    }
}

同期プラグインの手順では、前に示したプラグイン コードは、要求がエラーを含 むように追加の詳細を含むように構成されている場合、Web API で次のエラーを返します。

{
    "error": {
        "code": "0x8004418d",
        "message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey": "Plugin/ErrorRepro.SOError, ErrorRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2bee3e550ec0851",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey": "d5958631-b87e-eb11-a812-000d3a4f50a7",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey": "1",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey": "a3028bda-73c2-4eef-bcb5-157c5a4c323e",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory": "SystemFailure",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName": "SandboxWorkerNotAvailable",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode": "500",
        "@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a8004418d&client=platform",
        "@Microsoft.PowerApps.CDS.TraceText": "\r\n[ErrorRepro: ErrorRepro.SOError]\r\n[d5958631-b87e-eb11-a812-000d3a4f50a7: ErrorRepro.SOError: Create of account]\r\n\r\n",
        "@Microsoft.PowerApps.CDS.InnerError.Message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A"
    }
}

このエラーがプラグイン Tracelog にどのように記録されるかを次に示します。

Unhandled exception: 
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433Detail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ActivityId>48c5818e-4912-42f0-b1b6-e3bbe7ae013d</ActivityId>
  <ErrorCode>-2147204723</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <HelpLink i:nil="true" />
  <Message>The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433</Message>
  <Timestamp>2021-03-06T22:14:22.0629638Z</Timestamp>
  <ExceptionRetriable>false</ExceptionRetriable>
  <ExceptionSource>WorkerCommunication</ExceptionSource>
  <InnerFault i:nil="true" />
  <OriginalException>System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay)</OriginalException>
  <TraceText i:nil="true" />
</OrganizationServiceFault>

ワーカー プロセスがメモリ制限に達する

各ワーカー プロセスには、有限量のメモリがあります。 大量のデータを含む複数の同時実行操作が使用可能なメモリを超え、プロセス ワーカーがクラッシュする可能性がある条件があります。

RetrieveMultiple with File data

この場合の一般的なシナリオは、要求にファイル データが含まれる操作に対して RetrieveMultiple プラグインが実行される場合です。 たとえば、添付ファイルを含むメールを取得する場合などです。 このようなクエリで返される可能性のあるデータの量は、任意の数の添付ファイルに関連する電子メールがあり、添付ファイルのサイズが異なる可能性があるため、予測できません。

同じような性質の複数の要求が同時に実行されている場合、必要なメモリ量が大きくなります。 メモリの量が制限を超えると、プロセスがクラッシュします。 この状況を防ぐための鍵は、関連する添付ファイルを RetrieveMultiple 含むエンティティを含むクエリを制限することです。 を使用してレコードを RetrieveMultiple取得しますが、個々 Retrieve の操作を使用して必要に応じて関連ファイルを取得します。

メモリ リーク

あまり一般的ではないシナリオは、プラグイン内のコードがメモリをリークしている場合です。 この状況は、プラグインがステートレスとして記述されていない場合に発生する可能性があります。これはもう 1 つのベスト プラクティスです。 詳細については、「 プラグインの実装をステートレスとして開発する」を参照してください。 プラグインがステートレスではなく、配列のようなステートフル プロパティにデータを継続的に追加しようとすると、使用可能なすべてのメモリを使用する時点までデータの量が増加します。

トランザクション エラー

トランザクションに関連するエラーには、次の 2 つの一般的な種類があります。

エラー コード: -2146893812
エラー メッセージ: ISV コードにより、開いているトランザクション数が減少しました。 カスタム プラグインでは、OrganizationService 呼び出しの例外をキャッチして処理を続行しないでください。

エラー コード: -2147220911
エラー メッセージ: アクティブなトランザクションはありません。 通常、このエラーは、サービス呼び出しからのエラーを無視し、処理を続行するカスタム プラグインによって発生します。

注:

一番上のエラーが最近追加されました。 問題を含むプラグインのコンテキストで、すぐに発生する必要があります。 一番下のエラーは、通常はカスタム ワークフロー アクティビティを含むさまざまな状況で発生する可能性があります。 別のプラグインの問題が原因である可能性があります。

同期プラグイン内でデータ操作に関連するエラーが発生すると、操作全体のトランザクションが終了します。

詳細については、「 Microsoft Dataverse でのスケーラブルなカスタマイズ設計」を参照してください。

一般的な原因は、開発者が成功する 可能性のある 操作の実行を試みることができると考えているため、その操作をブロックに try/catch ラップし、失敗したときにエラーを飲み込もうとすることです。

このパターンはクライアント アプリケーションに対して機能する可能性があります。プラグインの実行中に、データ操作エラーが発生すると、トランザクション全体がロールバックされます。 エラーを飲み込むことはできないため、常に を InvalidPluginExecutionException返す必要があります。

エラー "Sql エラー: 実行タイムアウトの期限切れ"

エラー コード: -2147204783
エラー メッセージ: Sql エラー: '実行タイムアウトの有効期限が切れています。 操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。'

原因

SQL タイムアウト エラーが発生する理由はさまざまです。 そのうちの 3 つを次に示します。

ブロック

SQL タイムアウト エラーの最も一般的な原因は、操作が別の SQL トランザクションによってブロックされたリソースを待機していることです。 このエラーは、Dataverse がデータの整合性を保護し、ユーザーのパフォーマンスに影響を与える実行時間の長い要求から保護した結果です。

ブロックは、他の同時操作が原因である可能性があります。 コードは、テスト環境で分離して正常に動作し、プラグインで複数のユーザーがロジックを開始している場合にのみ発生する条件の影響を受ける可能性があります。

プラグインを記述するときは、スケーラブルなカスタマイズを設計する方法を理解することが不可欠です。 詳細については、「 Dataverse でのスケーラブルなカスタマイズ設計」を参照してください。

カスケード操作

レコードの割り当てや削除など、プラグインで実行する特定のアクションによって、関連レコードに対する連鎖操作が開始される可能性があります。 これらのアクションにより、関連レコードにロックが適用され、後続のデータ操作がブロックされ、SQL タイムアウトが発生する可能性があります。

これらのカスケード操作がプラグインのデータ操作に与える影響を考慮する必要があります。 詳細については、「 テーブルリレーションシップの動作」を参照してください。

これらの動作は環境間で異なる方法で構成できるため、環境が同じ方法で構成されていない限り、動作の再現が困難な場合があります。

新しいテーブルのインデックス

プラグインが最近作成したテーブルまたは列を使用して操作を実行している場合、インデックスを管理するための一部のAzure SQL機能が数日後に違いを生む可能性があります。

ユーザー特権によるエラー

クライアント アプリケーションでは、ユーザーが実行できないコマンドを無効にすることができます。 プラグイン内では、この機能がありません。 コードには、呼び出し元のユーザーに実行する権限がない自動化が含まれている場合があります。

[ユーザーのコンテキストで実行] の値をそのユーザーに設定することで、適切な権限を持つことがわかっているユーザー のコンテキストで実行 するようにプラグインを登録できます。 または、別のユーザーを偽装して操作を実行することもできます。 詳細については、以下を参照してください:

無効なユーザーのコンテキストでを実行するときのエラー

無効なユーザーのコンテキストでプラグインが実行されると、次のエラーが返されます。

エラー メッセージ: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: OrganizationContext=<Context> で SystemUserId=<User-ID を>持つユーザーが無効になっています。 無効なユーザーはシステムにアクセスできません。 このユーザーを有効にすることを検討してください。 また、ライセンスが割り当てられない場合、ユーザーは無効になります。

このエラーをトラブルシューティングするには、クエリを実行して、無効なユーザーに登録されている手順と、関連するプラグインと SdkMessage 詳細を見つけることができます。

https://<env-url>/api/data/v9.2/sdkmessageprocessingsteps
?$filter=_impersonatinguserid_value eq '<disabled-userId-from-error>'&
$expand=plugintypeid($select=name,friendlyname,assemblyname;
$expand=pluginassemblyid($select=solutionid,name,isolationmode)),sdkmessageid($select=solutionid,name)&
$select=solutionid,name,stage,_impersonatinguserid_value,mode

エラー "サンドボックスにコンテキストを送信するときにメッセージ サイズを超えました"

エラー コード: -2147220970
エラー メッセージ: コンテキストをサンドボックスに送信するときにメッセージ サイズを超えました。 メッセージ サイズ: ### Mb

このエラーは、メッセージ ペイロードが 116.85 MB を超え、メッセージにプラグインが登録されている場合に発生します。 エラー メッセージには、このエラーの原因となったペイロードのサイズが含まれています。

この制限は、アプリケーションを実行しているユーザーがリソースの制約に基づいて相互に干渉できないようにするのに役立ちます。 この制限は、Dataverse プラットフォームの可用性とパフォーマンス特性を脅かす、異常に大きなメッセージ ペイロードからの保護レベルを提供するのに役立ちます。

116.85 MB は十分な大きさであるため、このケースが発生することはまれです。 このケースが発生する可能性が最も高い状況は、大きなバイナリ ファイルを含む複数の関連レコードを含むレコードを取得する場合です。

このエラーが発生した場合は、次のことができます。

  1. メッセージのプラグインを削除します。 メッセージに登録されているプラグインがない場合、操作はエラーなしで完了します。
  2. カスタム クライアントでエラーが発生している場合は、1 回の操作で作業を実行しないようにコードを変更できます。 代わりに、小さな部分でデータを取得するコードを記述します。

エラー "指定されたキーがディクショナリに存在しなかった"

Dataverse は、キーと値のコレクションを表す抽象 DataCollection<TKey,TValue> クラスから派生したクラスを頻繁に使用します。 たとえば、プラグインでは、 IExecutionContextInputParameters プロパティは ParameterCollection クラスからDataCollection<TKey,TValue>派生した です。 これらのクラスは、基本的に、キー名を使用して特定の値にアクセスするディクショナリ オブジェクトです。

エラー コード

このエラーは、コード内のキー値がコレクションに存在しない場合に発生します。 その結果、実行時エラーではなくプラットフォーム エラーになります。 プラグイン内でこのエラーが発生した場合、エラー コードはエラーがキャッチされたかどうかによって異なります。

プラグインの例外を処理する」で説明されているように、開発者がInvalidPluginExecutionException例外をキャッチして を返した場合、次のエラーが返されます。

エラー コード: -2147220891
エラー メッセージ: ISV コードによって操作が中止されました。

ただし、このエラーでは、開発者が正しくキャッチせず、次のエラーが返されるのが一般的です。

エラー コード: -2147220956
エラー メッセージ: ISV コードから予期しないエラーが発生しました。

注:

"ISV" は 、独立系ソフトウェア ベンダーを表します。

原因

このエラーは設計時に頻繁に発生し、スペル ミスや大文字と小文字の誤りが原因である可能性があります。 キー値では大文字と小文字が区別されます。

実行時にエラーが発生するのは、値が存在しない場合に値が存在すると仮定した開発者が原因です。 たとえば、テーブルの更新用に登録されているプラグインでは、変更された値のみが .Attributes コレクションにEntity含まれます。

解決方法

このエラーを解決するには、キーを使用して値にアクセスする前に、キーが存在することをチェックする必要があります。

たとえば、テーブル列にアクセスするときは、 メソッドContains(String)を使用Entityして、次のコードに示すように、テーブルに列が存在するかどうかをチェックできます。

// Obtain the execution context from the service provider.  
IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

// The InputParameters collection contains all the data passed in the message request.  
if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    {
    // Obtain the target entity from the input parameters.  
    Entity entity = (Entity)context.InputParameters["Target"];

    //Check whether the name attribute exists.
    if(entity.Contains("name"))
    {
        string name = entity["name"];
    }

一部の開発者は、 メソッドをEntityGetAttributeValue<T>(String)使用して、テーブル列にアクセスするときにこのエラーを回避します。 列が存在しない場合、このメソッドは型の既定値を返します。 既定値が null の場合、このメソッドは期待どおりに動作します。 ただし、 のように DateTime既定値が null を返さない場合、返される値は 1/1/0001 00:00 null ではなく です。

エラー "現在のトランザクションで既に設定されているのとは異なる分離レベルのトランザクションを開始できません"

エラー コード: -2147220989
エラー メッセージ: 現在のトランザクションで既に設定されている分離レベルとは異なるトランザクションを開始することはできません

プラグインは、ビジネス ロジックをサポートすることを目的としています。 同期プラグイン内のデータ スキーマの一部の変更はサポートされていません。 これらの操作は時間がかかる場合が多く、アプリケーションで使用されるキャッシュされたメタデータが同期しなくなる可能性があります。ただし、これらの操作は、非同期的に実行するために登録されたプラグイン ステップで実行できます。

既知の問題: Activity.RegardingObjectId 名の値がプラグインで設定されていない

この問題の最も一般的な現象は、プライマリ名の属性値ではなく、アクティビティ レコードの [関連 ] フィールドが表示 (No Name) される点です。

プラグイン内では、 EntityReference 値を使用してルックアップ属性を設定できます。 EntityReference.Name プロパティは必要ありません。 通常、参照属性値を設定するときに含める必要はありません。これは、Dataverse によって設定されるためです。 イベント パイプラインの PreOperation ステージでは、このような値を設定する必要があります。 詳細については、「 イベント実行パイプライン」を参照してください。

この規則の例外は、 ActivityPointer.RegardingObjectId 参照を設定する場合です。 から ActivityPointer 派生したすべてのエンティティ型は、この参照を継承します。 既定では、予定チャットEmailFAXレターPhoneCallRecurringAppointmentMaster、およびアクティビティの種類として作成されたすべてのカスタム テーブルが含まれます。 詳細については、「 アクティビティ テーブル」を参照してください。

PreOperation ステージでこの値を設定した場合、名前の値は Dataverse によって追加されません。 値は null であり、この値を含める必要がある書式設定された値は、レコードを取得するときに存在しません。

回避策

この問題を回避するには、次の 2 つの方法があります。

  1. ルックアップ属性の値を設定する前に、 EntityReference.Name プロパティ値を正しいプライマリ名フィールド値で設定できます。
  2. 参照値は、PreOperation ステージではなく PreValidation ステージで設定できます。

詳細