Risolvere i problemi dei plug-in Dataverse
Questo articolo contiene informazioni sugli errori che possono verificarsi durante l'esecuzione del plug-in o sugli errori dataverse correlati ai plug-in e su come evitarli o correggerli.
Errore "Impossibile completare la conversione temporale"
Codice errore: -2147220956
Messaggio di errore: impossibile completare la conversione perché dataTime specificato non ha la proprietà Kind impostata correttamente. Ad esempio, quando la proprietà Kind è DateTimeKind.Local, il fuso orario di origine deve essere TimeZoneInfo.Local.
Questo errore può verificarsi durante una TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) chiamata nel codice plug-in per convertire un DateTime
valore nel fuso orario di Santiago o Volgograd in utc (Coordinated Universal Time).
Questo errore è causato da una limitazione nota del prodotto e attualmente non esiste alcuna soluzione alternativa.
Per altre informazioni, vedere Specificare le impostazioni del fuso orario per un utente.
Errore "Processo di lavoro sandbox arrestato in modo anomalo"
Codice di errore: -2147204723
Messaggio di errore: l'esecuzione del plug-in non è riuscita perché il processo di lavoro sandbox si è arrestato in modo anomalo. Ciò è in genere dovuto a un errore nel codice del plug-in.
Questo errore significa semplicemente che il processo di lavoro che esegue il codice plug-in si è arrestato in modo anomalo. Il plug-in potrebbe essere il motivo dell'arresto anomalo, ma potrebbe anche essere un altro plug-in in esecuzione simultaneamente per l'organizzazione. Poiché il processo si è arrestato in modo anomalo, non è possibile estrarre informazioni più specifiche sul motivo per cui si è verificato un arresto anomalo. Ma dopo aver esaminato i dati dei dump di arresto anomalo dopo il fatto, è stato rilevato che questo errore si verifica in genere a causa di uno dei quattro motivi seguenti:
- Eccezione non gestita nel plug-in
- Uso dei thread per accodare il lavoro senza try/catch nel delegato del thread
- Errore di Stack Overflow nel plug-in
- Il processo di lavoro raggiunge il limite di memoria
Eccezione non gestita nel plug-in
Quando si scrive un plug-in, è consigliabile provare ad anticipare quali operazioni potrebbero non riuscire ed eseguirne il wrapping in un blocco try-catch. Quando si verifica un errore, è necessario usare la InvalidPluginExecutionException classe per terminare normalmente l'operazione con un errore significativo per l'utente.
Per altre informazioni, vedere Gestire le eccezioni nei plug-in.
Uno scenario comune per questa eccezione è quando si usa il metodo HttpClient.SendAsync o HttpClient.GetAsync . Questi metodi HttpClient sono operazioni asincrone che restituiscono un oggetto Task. Per lavorare in un plug-in in cui il codice deve essere sincrono, gli utenti potrebbero usare l'oggetto TResult> attività<. Proprietà Result. Quando si verifica un errore, Result
restituisce un'eccezione AggregateException. Un AggregateException
consolida più errori in una singola eccezione, che può essere difficile da gestire. Una progettazione migliore consiste nell'usare Task<TResult>. GetAwaiter(). GetResult() perché propaga i risultati come l'errore specifico che ha causato l'errore.
L'esempio seguente illustra il modo corretto per gestire l'eccezione e una chiamata in uscita usando il metodo HttpClient.GetAsync . Questo plug-in tenta di ottenere il testo della risposta per un uri impostato nella configurazione non sicura per un passaggio registrato.
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);
}
}
}
}
Uso dei thread per accodare il lavoro senza try/catch nel delegato del thread
Non è consigliabile usare modelli di esecuzione parallela nei plug-in. Questo anti-pattern è definito nell'articolo sulle procedure consigliate: Non usare l'esecuzione parallela all'interno di plug-in e attività del flusso di lavoro. L'uso di questi modelli può causare problemi durante la gestione della transazione in un plug-in sincrono. Tuttavia, un altro motivo per cui non usare questi modelli è che qualsiasi lavoro eseguito all'esterno di un try
/catch
blocco in un delegato di thread può causare l'arresto anomalo del processo di lavoro.
Importante
Quando il processo di lavoro si arresta in modo anomalo, l'esecuzione del plug-in e di altri plug-in attualmente in esecuzione in tale processo verrà terminata. Sono inclusi i plug-in che non si possiedono o non si gestiscono.
Application Insights per il salvataggio
In passato, ottenere la traccia dello stack o altre informazioni di esecuzione per le eccezioni plug-in non gestite dal processo di lavoro in arresto anomalo era impossibile. Dataverse offre ora il supporto per la registrazione degli errori di esecuzione in Application Insights. Per abilitare questa funzione, è possibile collegare Application Insights all'ambiente in cui è registrato il plug-in. Una volta collegato, la registrazione degli arresti anomali del plug-in si verifica automaticamente.
Per altre informazioni, vedere Esportare dati in Application Insights.
Dopo aver collegato un ambiente di Application Insights, i dati seguenti di un arresto anomalo del processo di lavoro saranno disponibili per la risoluzione del problema.
Per passare al report di arresto anomalo in Application Insights, seguire questa procedura:
- Collegare Application Insights all'ambiente.
- Attendere che un'eccezione del plug-in restituisca l'errore di arresto anomalo del processo di lavoro.
- Nell'interfaccia di amministrazione di Power Platform passare ad Application Insights.
- Nella pagina Application Insights selezionare Errori nel pannello a sinistra.
- Nella pagina Errori selezionare Eccezioni.
- In EXCEPTION PROBLEM ID (ID problema eccezione) nell'elenco Complessivo selezionare Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException.
- Sul lato destro della pagina, in Generale, selezionare PluginWorkerCrashException. Verranno ora visualizzati i dettagli di tutte le eccezioni di arresto anomalo del processo di lavoro registrato.
- Search per e selezionare l'eccezione desiderata nel pannello sinistro e il report dei dettagli dell'eccezione verrà visualizzato sul lato destro della pagina (vedere lo screenshot precedente per un esempio).
- Per accedere alla traccia dello stack, espandere CrashDetails nel report.
Errore di overflow dello stack nel plug-in
Questo tipo di errore si verifica più frequentemente subito dopo aver apportato alcune modifiche al codice del plug-in. Alcune persone usano il proprio set di classi base per semplificare l'esperienza di sviluppo. A volte questi errori derivano dalle modifiche apportate alle classi di base da cui dipende un plug-in specifico.
Ad esempio, una chiamata ricorsiva senza una condizione di terminazione o una condizione di terminazione, che non copre tutti gli scenari, può causare questo errore. Per altre informazioni, vedere Le osservazioni sulla classe > StackOverflowException.
È consigliabile esaminare tutte le modifiche al codice applicate di recente per il plug-in e qualsiasi altro codice da cui dipende il codice del plug-in.
Esempio
Il codice plug-in seguente causa una StackOverflowException
causa di una chiamata ricorsiva senza limiti. Nonostante l'uso della traccia e il tentativo di acquisire l'errore, la traccia e l'errore non vengono restituiti perché il processo di lavoro che li elaborava terminava.
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");
}
}
}
In un passaggio del plug-in sincrono, il codice plug-in illustrato in precedenza restituisce l'errore seguente nell'API Web quando la richiesta è configurata per includere dettagli aggiuntivi con errori.
{
"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"
}
}
Di seguito viene illustrato come questo errore viene registrato nel log di traccia del plug-in:
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>
Il processo di lavoro raggiunge il limite di memoria
Ogni processo di lavoro ha una quantità limitata di memoria. Esistono condizioni in cui più operazioni simultanee che includono grandi quantità di dati potrebbero superare la memoria disponibile e causare l'arresto anomalo del ruolo di lavoro del processo.
RetrieveMultiple con dati file
Lo scenario comune, in questo caso, è quando viene eseguito un plug-in per un'operazione RetrieveMultiple
in cui la richiesta include dati di file. Ad esempio, quando si recuperano messaggi di posta elettronica che includono eventuali allegati di file. La quantità di dati che potrebbero essere restituiti in una query come questa è imprevedibile perché qualsiasi messaggio di posta elettronica potrebbe essere correlato a un numero qualsiasi di allegati di file e le dimensioni degli allegati possono variare.
Quando più richieste di natura simile vengono eseguite contemporaneamente, la quantità di memoria necessaria diventa grande. Se la quantità di memoria supera il limite, il processo si arresta in modo anomalo. La chiave per evitare questa situazione è limitare RetrieveMultiple
le query che includono entità con allegati file correlati. Recuperare i record usando RetrieveMultiple
, ma recuperare tutti i file correlati in base alle esigenze usando singole Retrieve
operazioni.
Perdite di memoria
Uno scenario meno comune è quello in cui il codice nel plug-in perde memoria. Questa situazione può verificarsi quando il plug-in non viene scritto come senza stato, che è un'altra procedura consigliata. Per altre informazioni, vedere Sviluppare implementazioni di plug-in come senza stato. Quando il plug-in non è senza stato ed è in atto un tentativo di aggiungere continuamente dati a una proprietà con stato come una matrice, la quantità di dati aumenta fino al punto in cui usa tutta la memoria disponibile.
Errori di transazione
Esistono due tipi comuni di errori correlati alle transazioni:
Codice errore: -2146893812
Messaggio di errore: il codice ISV ha ridotto il numero di transazioni aperte. I plug-in personalizzati non devono intercettare le eccezioni dalle chiamate OrganizationService e continuare l'elaborazione.
Codice errore: -2147220911
Messaggio di errore: nessuna transazione attiva. Questo errore è in genere causato da plug-in personalizzati che ignorano gli errori delle chiamate al servizio e continuano l'elaborazione.
Nota
L'errore principale è stato aggiunto più di recente. Deve verificarsi immediatamente e nel contesto del plug-in che contiene il problema. L'errore inferiore può comunque verificarsi in circostanze diverse, in genere coinvolgendo attività del flusso di lavoro personalizzate. Potrebbe essere dovuto a problemi in un altro plug-in.
Ogni volta che si verifica un errore correlato a un'operazione sui dati all'interno di un plug-in sincrono, la transazione per l'intera operazione viene terminata.
Per altre informazioni, vedere Progettazione della personalizzazione scalabile in Microsoft Dataverse.
Una causa comune è che uno sviluppatore ritiene di poter tentare di eseguire un'operazione che potrebbe avere esito positivo, quindi esegue il wrapping di tale operazione in un try
/catch
blocco e tenta di ingoiare l'errore quando ha esito negativo.
Anche se questo modello può funzionare per un'applicazione client, all'interno dell'esecuzione di un plug-in, qualsiasi errore di operazione sui dati comporta il rollback dell'intera transazione. Non è possibile ingoiare l'errore, quindi è necessario assicurarsi di restituire sempre un InvalidPluginExecutionExceptionoggetto .
Errore "Errore SQL: timeout di esecuzione scaduto"
Codice di errore: -2147204783
Messaggio di errore: Errore SQL: 'Timeout di esecuzione scaduto. Il periodo di timeout trascorso prima del completamento dell'operazione o il server non risponde."
Causa
Esistono diversi motivi per cui potrebbe verificarsi un errore di timeout di SQL. Tre di essi sono descritti qui:
Blocco
La causa più comune di un errore di timeout SQL è che l'operazione è in attesa di risorse bloccate da un'altra transazione SQL. L'errore è il risultato di Dataverse che protegge l'integrità dei dati e da richieste a esecuzione prolungata che influiscono sulle prestazioni per gli utenti.
Il blocco potrebbe essere dovuto ad altre operazioni simultanee. Il codice potrebbe funzionare correttamente in isolamento in un ambiente di test ed essere comunque soggetto a condizioni che si verificano solo quando più utenti avviano la logica nel plug-in.
Quando si scrivono plug-in, è essenziale comprendere come progettare personalizzazioni scalabili. Per altre informazioni, vedere Progettazione di personalizzazioni scalabili in Dataverse.
Operazioni a cascata
Alcune azioni eseguite nel plug-in, ad esempio l'assegnazione o l'eliminazione di un record, possono avviare operazioni a catena sui record correlati. Queste azioni potrebbero applicare blocchi a record correlati che causano il blocco delle successive operazioni sui dati, che a loro volta possono causare un timeout di SQL.
È consigliabile considerare il possibile impatto di queste operazioni a catena sulle operazioni sui dati nel plug-in. Per altre informazioni, vedere Comportamento della relazione tra tabelle.
Poiché questi comportamenti possono essere configurati in modo diverso tra gli ambienti, il comportamento potrebbe essere difficile da riprodurre a meno che gli ambienti non siano configurati nello stesso modo.
Indici nelle nuove tabelle
Se il plug-in esegue operazioni usando una tabella o una colonna creata di recente, alcune funzionalità di Azure SQL per gestire gli indici potrebbero fare la differenza dopo alcuni giorni.
Errori dovuti a privilegi utente
In un'applicazione client è possibile disabilitare i comandi che gli utenti non possono eseguire. All'interno di un plug-in, non si ha questa capacità. Il codice potrebbe includere un'automazione che l'utente chiamante non dispone dei privilegi da eseguire.
È possibile registrare il plug-in per l'esecuzione nel contesto di un utente noto per avere i privilegi corretti impostando il valore Esegui nel contesto dell'utente su tale utente. In alternativa, è possibile eseguire l'operazione rappresentando un altro utente. Per ulteriori informazioni consulta:
Errore durante l'esecuzione nel contesto di un utente disabilitato
Quando un plug-in viene eseguito nel contesto di un utente disabilitato, viene restituito l'errore seguente:
Messaggio di errore: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: L'utente con SystemUserId=<User-ID> in OrganizationContext=<Context> è disabilitato. Gli utenti disabilitati non possono accedere al sistema. Prendere in considerazione l'abilitazione di questo utente. Inoltre, gli utenti vengono disabilitati se non hanno una licenza assegnata.
Per risolvere questo errore, è possibile eseguire una query per trovare i passaggi registrati per l'utente disabilitato, nonché il plug-in associato e SdkMessage
i dettagli.
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
Errore "Dimensione del messaggio superata durante l'invio del contesto alla sandbox"
Codice errore: -2147220970
Messaggio di errore: dimensioni dei messaggi superate durante l'invio del contesto alla sandbox. Dimensioni del messaggio: ### Mb
Questo errore si verifica quando un payload del messaggio è maggiore di 116,85 MB e viene registrato un plug-in per il messaggio. Il messaggio di errore include le dimensioni del payload che ha causato l'errore.
Il limite consente di garantire che gli utenti che eseguono applicazioni non possano interferire tra loro in base ai vincoli di risorse. Il limite consente di fornire un livello di protezione da payload di messaggi insolitamente grandi che minacciano le caratteristiche di disponibilità e prestazioni della piattaforma Dataverse.
116,85 MB è sufficientemente grande che dovrebbe essere raro riscontrare questo caso. La situazione più probabile in cui questo caso potrebbe verificarsi è quando si recupera un record con più record correlati che includono file binari di grandi dimensioni.
Se viene visualizzato questo errore, è possibile:
- Rimuovere il plug-in per il messaggio. Se non sono presenti plug-in registrati per il messaggio, l'operazione viene completata senza errori.
- Se l'errore si verifica in un client personalizzato, è possibile modificare il codice in modo che non tenti di eseguire il lavoro in una singola operazione. Scrivere invece codice per recuperare i dati in parti più piccole.
Errore "La chiave specificata non era presente nel dizionario"
Dataverse usa spesso classi derivate dalla classe astratta DataCollection<TKey,TValue> che rappresenta una raccolta di chiavi e valori. Ad esempio, con i plug-in, la IExecutionContextproprietà .InputParameters è un ParameterCollection oggetto derivato dalla DataCollection<TKey,TValue> classe . Queste classi sono essenzialmente oggetti dizionario in cui si accede a un valore specifico usando il nome della chiave.
Codici di errore
Questo errore si verifica quando il valore della chiave nel codice non esiste nella raccolta. Il risultato è un errore di runtime piuttosto che un errore della piattaforma. Quando questo errore si verifica all'interno di un plug-in, il codice di errore dipende dal fatto che l'errore sia stato rilevato.
Se lo sviluppatore rileva l'eccezione e restituisce InvalidPluginExecutionException, come descritto in Gestire le eccezioni nei plug-in, viene restituito l'errore seguente:
Codice errore: -2147220891
Messaggio di errore: il codice ISV ha interrotto l'operazione.
Tuttavia, con questo errore, è comune che lo sviluppatore non lo intercetti correttamente e viene restituito l'errore seguente:
Codice errore: -2147220956
Messaggio di errore: si è verificato un errore imprevisto dal codice ISV.
Nota
"ISV" è l'acronimo di Independent Software Vendor.
Causa
Questo errore si verifica spesso in fase di progettazione e può essere causato da un errore di ortografia o dall'uso di maiuscole e minuscole non corrette. I valori chiave fanno distinzione tra maiuscole e minuscole.
In fase di esecuzione, l'errore è spesso dovuto allo sviluppatore che presuppone che il valore sia presente quando non lo è. Ad esempio, in un plug-in registrato per l'aggiornamento di una tabella, solo i valori modificati vengono inclusi nella Entityraccolta .Attributes
Risoluzione
Per risolvere questo errore, è necessario verificare che la chiave esista prima di tentare di usarla per accedere a un valore.
Ad esempio, quando si accede a una colonna di tabella, è possibile utilizzare il Entitymetodo .Contains(String) per verificare se una colonna esiste in una tabella, come illustrato nel codice seguente.
// 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"];
}
Alcuni sviluppatori usano il Entitymetodo .GetAttributeValue<T>(String) per evitare questo errore durante l'accesso a una colonna di tabella. Questo metodo restituisce il valore predefinito del tipo se la colonna non esiste. Se il valore predefinito è Null, questo metodo funziona come previsto. Tuttavia, se il valore predefinito non restituisce null, ad esempio con , DateTime
il valore restituito è 1/1/0001 00:00
anziché Null.
Errore "Non è possibile avviare una transazione con un livello di isolamento diverso da quello già impostato nella transazione corrente"
Codice errore: -2147220989
Messaggio di errore: non è possibile avviare una transazione con un livello di isolamento diverso da quello già impostato nella transazione corrente
I plug-in sono progettati per supportare la logica di business. La modifica di qualsiasi parte dello schema dei dati all'interno di un plug-in sincrono non è supportata. Queste operazioni richiedono spesso più tempo e potrebbero causare la non sincronizzazione dei metadati memorizzati nella cache usati dalle applicazioni. Tuttavia, queste operazioni possono essere eseguite in un passaggio plug-in registrato per l'esecuzione asincrona.
Problema noto: Il valore del nome Activity.RegardingObjectId non è impostato con il plug-in
Il sintomo più comune di questo problema è che il campo Regarding in un record di attività mostra (No Name)
anziché il valore dell'attributo del nome primario.
All'interno di un plug-in, è possibile impostare gli attributi di ricerca con un valore EntityReference . La proprietà EntityReference.Name non è obbligatoria. In genere, non è necessario includerlo quando si imposta un valore dell'attributo di ricerca perché dataverse lo imposta. È consigliabile impostare valori come questo durante la fase di pre-operazione della pipeline di eventi. Per altre informazioni, vedere Pipeline di esecuzione di eventi.
L'eccezione a questa regola si verifica quando si imposta la ricerca ActivityPointer.RegardingObjectId . Tutti i tipi di entità derivati da ActivityPointer
ereditano questa ricerca. Per impostazione predefinita, sono inclusi Appointment, Chat, Email, Fax, Letter, PhoneCall, RecurringAppointmentMaster ed eventuali tabelle personalizzate create come tipi di attività. Per altre informazioni, vedere Tabelle attività.
Se si imposta questo valore nella fase PreOperation , il valore del nome non viene aggiunto da Dataverse. Il valore è Null e il valore formattato che deve contenere questo valore non è presente quando si recupera il record.
Soluzione alternativa
Esistono due modi per risolvere questo problema:
- È possibile impostare il valore della proprietà EntityReference.Name con il valore del campo del nome primario corretto prima di impostare il valore dell'attributo di ricerca.
- È possibile impostare il valore di ricerca nella fase di preconvalida anziché nella fase di pre-operazione .