共用方式為


針對 Dataverse 外掛程式進行疑難解答

本文包含外掛程式執行期間可能發生的錯誤相關信息,或與外掛程式相關的 Dataverse 錯誤,以及如何避免或修正錯誤。

錯誤「無法完成時間轉換」

錯誤碼: -2147220956
錯誤訊息:轉換無法完成,因為提供的 DataTime 未正確設定 Kind 屬性。 例如,當 Kind 屬性為 DateTimeKind.Local 時,來源時區必須是 TimeZoneInfo.Local。

在外掛程式程式代碼的呼叫期間 TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) ,可能會發生此錯誤,將聖地牙哥或伏爾戈格勒時區中的值轉換為 DateTime 國際標準時間(UTC)。

此錯誤是由已知的產品限制所造成,目前沒有因應措施。

如需詳細資訊,請參閱 指定使用者的時區設定。

錯誤「沙盒背景工作進程當機」

錯誤碼: -2147204723
錯誤訊息:外掛程式執行失敗,因為沙箱背景工作進程當機。 這通常是因為外掛程式代碼發生錯誤。

此錯誤只是表示執行外掛程式程式代碼的背景工作進程當機。 您的外掛程式可能是當機的原因,但它也可能是組織同時執行的另一個外掛程式。 因為進程當機,我們無法擷取其當機原因的任何更具體資訊。 但在檢查發生損毀傾印的數據之後,我們發現此錯誤通常是因為下列四個原因之一而發生:

外掛程式中未處理的例外狀況

當您撰寫外掛程式時,您應該嘗試預測哪些作業可能會失敗,並將其包裝在 try-catch 區塊中。 發生錯誤時,您應該使用 InvalidPluginExecutionException 類別,以正常方式終止作業,對用戶有意義的錯誤。

如需詳細資訊,請參閱 處理外掛程式中的例外狀況

此例外狀況的常見案例是使用 HttpClient.SendAsync 或 HttpClient.GetAsync 方法時。 這些 HttpClient 方法是傳回 Task異步操作。 若要在程式代碼需要同步的外掛程式中工作,人們可能會使用 Task<TResult>。Result 屬性。 發生錯誤時, Result 會傳 回 AggregateException。 會將 AggregateException 多個失敗合併成單一例外狀況,而這可能會難以處理。 更好的設計是使用 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

您不應該在外掛程式中使用平行執行模式。在最佳做法文章中會指出此反模式: 請勿在外掛程式和工作流程活動中使用平行執行。 使用這些模式可能會導致在同步外掛程式中管理交易時發生問題。 不過,不使用這些模式的另一個原因是線程委派中區塊外 try/catch 完成的任何工作都可能會使背景工作進程當機。

重要

當背景工作進程當機時,執行外掛程式和其他目前在該進程中執行的外掛程式將會終止。 這包括您不擁有或維護的外掛程式。

救援的 Application Insights

在過去,無法從當機的背景工作進程取得未處理的外掛程式例外狀況的堆疊追蹤或其他執行資訊。 不過,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. [例外狀況問題標識符] 下方的 [整體] 列表中,選取 [Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException]。
  7. 在頁面右側的 [整體] 底下,選取 [PluginWorkerCrashException]。 您現在會看到所有記錄的背景工作進程當機例外狀況詳細數據。
  8. 搜尋並選取左側面板中所需的例外狀況,且例外狀況詳細數據報告會顯示在頁面右側(如需範例,請參閱上述螢幕快照)。
  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>

背景工作進程達到記憶體限制

每個背景工作進程都有有限的記憶體數量。 在某些情況下,包含大量數據的多個並行作業可能會超過可用的記憶體,並導致進程背景工作角色當機。

使用檔案數據擷取Multiple

在此案例中,常見案例是當外掛程式針對 RetrieveMultiple 要求包含檔案數據的作業執行時。 例如,擷取包含任何檔案附件的電子郵件時。 這類查詢中可能傳回的數據量是無法預測的,因為任何電子郵件可能與任意數目的檔案附件有關,而附件的大小可能會有所不同。

當類似性質的多個要求同時執行時,所需的記憶體數量就會變得很大。 如果記憶體數量超過限制,進程就會當機。 防止這種情況的關鍵是限制 RetrieveMultiple 包含具有相關檔案附件之實體的查詢。 使用 RetrieveMultiple擷取記錄,但視需要使用個別 Retrieve 作業擷取任何相關檔案。

記憶體流失

較不常見的案例是外掛程式中的程式碼流失記憶體。 當外掛程式未寫入為無狀態時,就會發生這種情況,這是另一個最佳做法。 如需詳細資訊,請參閱 將外掛程式實作開發為無狀態。 當外掛程式不是無狀態,而且嘗試持續將數據加入數位等具狀態屬性時,數據量就會成長到使用所有可用記憶體的點。

交易錯誤

交易有兩種常見的錯誤類型:

錯誤碼: -2146893812
錯誤訊息:ISV 程式代碼減少了開啟的交易計數。 自定義外掛程式不應該攔截來自 OrganizationService 呼叫的例外狀況,並繼續處理。

錯誤碼: -2147220911
錯誤訊息:沒有作用中交易。 此錯誤通常是由忽略服務呼叫錯誤並繼續處理的自定義外掛程式所造成。

注意

最近新增了前一個錯誤。 它應該會在包含問題的外掛程式內容中立即發生。 底部錯誤仍可能發生在不同情況下,通常涉及自定義工作流程活動。 這可能是因為另一個外掛程式發生問題。

每當與數據作業相關的錯誤發生在同步外掛程式內時,整個作業的交易就會結束。

如需詳細資訊,請參閱 Microsoft Dataverse 中的可調整自定義設計。

常見的原因是開發人員認為他們可以嘗試執行可能成功的作業,因此會在區塊中try/catch包裝該作業,並在失敗時嘗試吞下錯誤。

雖然此模式可能適用於用戶端應用程式,但在外掛程式執行期間,任何數據作業失敗都會導致回復整個交易。 您無法吞下錯誤,因此請務必一律傳回 InvalidPluginExecutionException

錯誤「Sql 錯誤:執行逾時已過期」

錯誤碼: -2147204783
錯誤訊息:Sql 錯誤:「執行逾時已過期。 作業完成之前經過的逾時期間,或伺服器沒有回應。

原因

SQL 逾時錯誤可能發生的原因有很多種。 其中三個如下所述:

封鎖

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. 如果錯誤發生在自定義用戶端中,您可以修改程式碼,使其不會嘗試在單一作業中執行工作。 相反地,撰寫程式代碼以擷取較小部分的數據。

錯誤「指定的索引鍵不存在於字典中」

Dataverse 經常使用衍生自抽象 DataCollection<TKey,TValue> 類的類別,代表索引鍵和值的集合。 例如,使用外掛程式時,IExecutionContext. 屬性是ParameterCollection衍生自 類別的 DataCollection<TKey,TValue>InputParameters 。 這些類別基本上是您使用索引鍵名稱存取特定值的字典物件。

錯誤碼

當程式代碼中的索引鍵值不存在於集合中時,就會發生此錯誤。 結果是運行時錯誤,而不是平台錯誤。 當外掛程式內發生此錯誤時,錯誤碼取決於錯誤是否已攔截。

如果開發人員攔截到例外狀況並傳InvalidPluginExecutionException回 ,如處理外掛程式中的例外狀況中所述,則會傳回下列錯誤:

錯誤碼: -2147220891
錯誤訊息:ISV 程式代碼中止作業。

不過,發生此錯誤時,開發人員通常無法正確攔截錯誤,並傳回下列錯誤:

錯誤碼: -2147220956
錯誤訊息:ISV 程式代碼發生非預期的錯誤。

注意

“ISV” 代表 獨立軟體廠商

原因

此錯誤經常在設計時間發生,可能是因為拼錯或使用不正確的大小寫所造成。 索引鍵值會區分大小寫。

在運行時間,錯誤通常是因為開發人員假設值不存在時存在。 例如,在為數據表更新註冊的外掛程式中,只有那些變更的值會包含在集合中EntityAttributes

解決方法

若要解決此錯誤,您必須先檢查密鑰是否存在,再嘗試使用它來存取值。

例如,存取數據表數據行時,您可以使用 Entity.Contains(String) 方法來檢查數據表中是否有數據行,如下列程式代碼所示。

// 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"];
    }

有些開發人員會使用 Entity.GetAttributeValue<T>(String) 方法來避免存取資料表數據行時發生此錯誤。 如果數據行不存在,這個方法會傳回型別的預設值。 如果預設值為 null,這個方法會如預期般運作。 但是,如果預設值未傳回 Null,例如使用 DateTime,則傳回的值是 1/1/0001 00:00 而非 Null。

錯誤「您無法啟動與目前交易上已設定不同的隔離等級的交易」

錯誤碼: -2147220989
錯誤訊息:您無法啟動與目前交易上已設定不同的隔離等級的交易

外掛程式旨在支援商業規則。 不支援在同步外掛程式內修改數據架構的任何部分。 這些作業經常需要較長的時間,而且可能會導致應用程式所使用的快取元數據變得同步。不過,這些作業可以在註冊以異步方式執行的外掛程式步驟中執行。

已知問題:Activity.RegardingObjectId 名稱值未設定外掛程式

此問題最常見的徵兆是 活動記錄中的 [關於 ] 字段會顯示 (No Name) ,而不是主要名稱屬性值。

在外掛程式內,您可以使用 EntityReference 值來設定查閱屬性不需要 EntityReference.Name 屬性。 一般而言,設定查閱屬性值時不需要包含它,因為 Dataverse 會設定它。 您應該在事件管線的 PreOperation 階段中設定如下的值。 如需詳細資訊,請參閱 事件執行管線

此規則的例外狀況是在設定 ActivityPointer.RegardingObjectId 查閱時。 衍生自 ActivityPointer 的所有實體類型都會繼承此查閱。 這些預設包括 AppointmentChatEmailFaxLetterPhoneCallRecurringAppointmentMaster,以及建立為活動類型的任何自定義數據表。 如需詳細資訊,請參閱 活動數據表

如果您在 PreOperation 階段中設定此值,Dataverse 不會新增名稱值。 值為 null,而且當您擷取記錄時,應該包含此值的格式化值不存在。

因應措施

有兩種方式可以解決此問題:

  1. 您可以在設定查閱屬性的值之前,使用正確的主名稱域值來設定 EntityReference.Name 屬性值。
  2. 您可以在 PreValidation 階段中設定查閱值,而不是 PreOperation 階段。

其他相關資訊