本文包含外掛程式執行期間可能發生的錯誤相關信息,或與外掛程式相關的 Dataverse 錯誤,以及如何避免或修正錯誤。
錯誤「無法完成時間轉換」
錯誤碼: -2147220956
錯誤訊息:轉換無法完成,因為提供的 DataTime 未正確設定 Kind 屬性。 例如,當 Kind 屬性為 DateTimeKind.Local 時,來源時區必須是 TimeZoneInfo.Local。
在外掛程式程式碼中進行 TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) 呼叫期間,可能會發生此錯誤,將在聖地牙哥或伏爾戈格勒時區中的值轉換為國際標準時間(UTC) DateTime
。
此錯誤是由已知的產品限制所造成,目前沒有因應措施。
如需詳細資訊,請參閱 指定使用者的時區設定。
錯誤「沙盒背景工作進程當機」
錯誤碼: -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 連結至您的環境。
- 等候外掛程式例外狀況導致背景工作進程當機錯誤。
- 在 Power Platform 系統管理中心中,流覽至 Application Insights。
- 在 [Application Insights] 頁面上,選取 左面板中的 [失敗 ]。
- 在 [ 失敗] 頁面上,選取 [ 例外狀況]。
- 在 [例外狀況問題標識符] 下方的 [整體] 列表中,選取 [Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException]。
- 在頁面右側的 [整體] 底下,選取 [PluginWorkerCrashException]。 您現在會看到所有記錄的背景工作進程當機例外狀況詳細數據。
- 搜尋並選取左側面板中所需的例外狀況,且例外狀況詳細數據報告會顯示在頁面右側(如需範例,請參閱上述螢幕快照)。
- 若要存取堆疊追蹤,請展開 報表中的 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& 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: #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& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay)</OriginalException>
<TraceText i:nil="true" />
</OrganizationServiceFault>
背景工作進程達到記憶體限制
每個背景工作進程都有有限的記憶體數量。 在某些情況下,包含大量數據的多個並行作業可能會超過可用的記憶體,造成進程工作程序當機。
使用檔案數據擷取Multiple
在此案例中,常見案例是當外掛程式針對 RetrieveMultiple
要求包含檔案數據的作業執行時。 例如,擷取包含任何檔案附件的電子郵件時。 這類查詢中可能傳回的數據量是無法預測的,因為任何電子郵件可能與任意數目的檔案附件有關,而附件的大小可能會有所不同。
當類似性質的多個要求同時執行時,所需的記憶體數量就會變得很大。 如果記憶體數量超過限制,進程就會當機。 防止這種情況的關鍵是限制 RetrieveMultiple
包含具有相關檔案附件之實體的查詢。 使用 RetrieveMultiple
擷取記錄,但視需要使用個別 Retrieve
作業擷取任何相關檔案。
記憶體流失
較不常見的案例是外掛程式中的程式碼流失記憶體。 當外掛程式未設計為無狀態時,可能會發生此情況,而設計為無狀態則是另一項最佳實踐。 如需詳細資訊,請參閱 將外掛程式實作開發為無狀態。 當插件不是無狀態,並且嘗試持續將數據添加到如陣列這樣的具狀態屬性時,數據量就會逐漸增長,直到使用所有可用的記憶體為止。
交易錯誤
交易有兩種常見的錯誤類型:
錯誤碼: -2146893812
錯誤訊息:ISV 程式代碼減少了開啟的交易計數。 自定義外掛程式不應該攔截來自 OrganizationService 呼叫的例外狀況,並繼續處理。
錯誤碼: -2147220911
錯誤訊息:沒有作用中交易。 此錯誤通常是由忽略服務呼叫錯誤並繼續處理的自定義外掛程式所造成。
注意
最新新增的是最上面的錯誤。 它應該會在包含問題的外掛程式內容中立即發生。 底部錯誤仍可能發生在不同情況下,通常涉及自定義工作流程活動。 這可能是因為另一個外掛程式發生問題。
每當與數據作業相關的錯誤發生在同步外掛程式內時,整個作業的交易就會結束。
如需詳細資訊,請參閱 Microsoft Dataverse 中的可調整自定義設計。
常見的原因是開發人員認為他們可以嘗試執行可能成功的作業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 足夠大,因此應該很少會遇到這種情況。 最有可能發生的情況是,當您擷取具有多個相關記錄且這些記錄包含大型二進位檔時,可能會出現此情況。
如果您收到此錯誤,您可以:
- 移除訊息的外掛程式。 如果沒有登錄訊息的外掛程式,作業就會完成,而不會發生錯誤。
- 如果錯誤發生在自定義用戶端中,您可以修改程式碼,使其不會嘗試在單一作業中執行工作。 相反地,撰寫程式代碼以擷取較小部分的數據。
錯誤「指定的索引鍵不存在於字典中」
Dataverse 經常使用從抽象 DataCollection<TKey,TValue> 類衍生的類別,來表示索引鍵和值的集合。 例如,使用外掛程式時,屬性IExecutionContext是一個從類別DataCollection<TKey,TValue>衍生的ParameterCollection。 這些類別基本上是您使用索引鍵名稱存取特定值的字典物件。
錯誤碼
當程式代碼中的索引鍵值不存在於集合中時,就會發生此錯誤。 結果是運行時錯誤,而不是平台錯誤。 當外掛程式內發生此錯誤時,錯誤碼取決於錯誤是否已攔截。
如果開發人員攔截到例外狀況並傳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
的所有實體類型都會繼承此查表功能。 這些預設包括 Appointment、 Chat、 Email、 Fax、 Letter、 PhoneCall、 RecurringAppointmentMaster,以及建立為活動類型的任何自定義數據表。 如需詳細資訊,請參閱 活動數據表。
如果您在 PreOperation 階段中設定此值,Dataverse 不會新增名稱值。 值為 null,而且當您擷取記錄時,應該包含此值的格式化值不存在。
因應措施
有兩種方式可以解決此問題:
- 您可以在設定查閱屬性的值之前,使用正確的主名稱域值來設定 EntityReference.Name 屬性值。
- 您可以在 PreValidation 階段中設定查閱值,而不是 PreOperation 階段。