Condividi tramite


Risolvere i problemi dei plug-in Dataverse

Questo articolo contiene informazioni sugli errori che possono verificarsi durante l'esecuzione del plug-in o errori di Dataverse correlati ai plug-in e su come evitarli o correggerli.

Errore "Impossibile completare la conversione dell'ora"

Codice errore: -2147220956
Messaggio di errore: impossibile completare la conversione perché la proprietà Kind specificata non è 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 Santiago o Volgograd in utc (Coordinated Universal Time).

Questo errore è causato da una limitazione del prodotto nota 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 errore: -2147204723
Messaggio di errore: l'esecuzione del plug-in non è riuscita perché il processo di lavoro sandbox si è arrestato in modo anomalo. Questo è in genere dovuto a un errore nel codice 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 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 l'arresto anomalo. Tuttavia, dopo aver esaminato i dati dai 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

Quando si scrive un plug-in, è consigliabile provare a prevedere 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'attività. Per lavorare in un plug-in in cui il codice deve essere sincrono, gli utenti potrebbero usare Task <TResult>. 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 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 protetta 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 di thread per accodare il lavoro senza try/catch nel delegato del thread

Non è consigliabile usare modelli di esecuzione paralleli nei plug-in. Questo anti-modello viene chiamato 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 di gestione della transazione in un plug-in sincrono. Tuttavia, un altro motivo per cui non usare questi modelli è che qualsiasi lavoro svolto all'esterno di un blocco in un try/catch delegato di thread può arrestare in modo anomalo il 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 terminerà. Sono inclusi i plug-in di cui non si è proprietari o che non si mantengono.

Application Insights per il salvataggio

In passato, ottenere l'analisi dello stack o altre informazioni sull'esecuzione per le eccezioni plug-in non gestite dal processo di lavoro arrestato in modo anomalo era impossibile. Dataverse offre tuttavia 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 i dati in Application Insights.

Dopo aver collegato un ambiente Application Insights, per la risoluzione del problema saranno disponibili i dati seguenti di un arresto anomalo del processo di lavoro.

Esempio di un report di arresto anomalo del plug-in di Application Insights.

Per passare al report di arresto anomalo in Application Insights, seguire questa procedura:

  1. Collegare Application Insights all'ambiente.
  2. Attendere che un'eccezione plug-in restituisca l'errore di arresto anomalo del processo di lavoro.
  3. Nell'interfaccia di amministrazione di Power Platform passare ad Application Insights.
  4. Nella pagina Application Insights selezionare Errori nel pannello sinistro.
  5. Nella pagina Errori selezionare Eccezioni.
  6. Nell'elenco Generale in ID problema eccezione selezionare Microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException.
  7. 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 registrate.
  8. Cercare 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).
  9. Per accedere all'analisi 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 nel codice del plug-in. Alcune persone usano il proprio set di classi di base per semplificare l'esperienza di sviluppo. A volte questi errori derivano dalle modifiche apportate a tali classi di base da cui dipende un particolare plug-in.

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 le modifiche al codice applicate di recente per il plug-in e qualsiasi altro codice da cui dipende il codice plug-in.

Esempio

Il codice plug-in seguente causa una StackOverflowException 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 viene registrato questo errore nel plug-in 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>

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 processo di lavoro.

RetrieveMultiple con dati di file

Lo scenario comune, in questo caso, è quando viene eseguito un plug-in per un'operazione RetrieveMultiple in cui la richiesta include i dati dei file. Ad esempio, quando si recuperano messaggi di posta elettronica che includono eventuali allegati di file. La quantità di dati che potrebbe essere restituita in una query come questa è imprevedibile perché qualsiasi messaggio di posta elettronica potrebbe essere correlato a un numero qualsiasi di allegati di file e gli allegati possono variare in base alle dimensioni.

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 impedire questa situazione è limitare RetrieveMultiple le query che includono entità con allegati di 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 è il caso 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 del plug-in come senza stato. Quando il plug-in non è senza stato e si tenta 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 dalle chiamate al servizio e continuano l'elaborazione.

Note

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 che coinvolgono 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 di 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, in modo che esegua il wrapping di tale operazione in un try/catch blocco e tenti di inghiottire l'errore quando non riesce.

Anche se questo modello potrebbe funzionare per un'applicazione client, all'interno dell'esecuzione di un plug-in, qualsiasi errore di operazione dati comporta il rollback dell'intera transazione. Non è possibile inghiottire l'errore, quindi è necessario assicurarsi di restituire sempre un oggetto InvalidPluginExecutionException.

Errore "Errore SQL: Timeout di esecuzione scaduto"

Codice 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 può verificarsi un errore di timeout SQL. Di seguito sono descritte tre di esse:

Processi bloccati

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 dalle richieste a esecuzione prolungata che influisce 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 della personalizzazione scalabile in Dataverse.

Operazioni a catena

Alcune azioni eseguite nel plug-in, ad esempio l'assegnazione o l'eliminazione di un record, possono avviare operazioni a catena su record correlati. Queste azioni possono applicare blocchi ai record correlati, causando il blocco delle operazioni di dati successive, che a sua volta possono causare un timeout SQL.

È consigliabile considerare il possibile impatto di queste operazioni a catena sulle operazioni sui dati nel plug-in. Per altre informazioni, vedere Comportamento delle relazioni 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 ai 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 altre informazioni, vedi:

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. Valutare la possibilità di abilitare 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 e SdkMessage i dettagli associati.

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 "Dimensioni del messaggio superate durante l'invio del contesto a Sandbox"

Codice errore: -2147220970
Messaggio di errore: le dimensioni dei messaggi sono stati superati durante l'invio del contesto a Sandbox. Dimensioni 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 questo errore.

Il limite garantisce che gli utenti che eseguono applicazioni non possano interferire tra loro in base ai vincoli delle risorse. Il limite consente di fornire un livello di protezione da payload di messaggi insolitamente di grandi dimensioni che minacciano le caratteristiche di disponibilità e prestazioni della piattaforma Dataverse.

116,85 MB è abbastanza grande che dovrebbe essere raro incontrare questo caso. La situazione più probabile in cui questo caso può verificarsi è quando si recupera un record con più record correlati che includono file binari di grandi dimensioni.

Se viene visualizzato questo errore, è possibile:

  1. Rimuovere il plug-in per il messaggio. Se non sono presenti plug-in registrati per il messaggio, l'operazione viene completata senza errori.
  2. Se si verifica l'errore 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 derivato dalla DataCollection<TKey,TValue> classe . Queste classi sono essenzialmente oggetti dizionari 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 ha rilevato l'eccezione e restituito InvalidPluginExecutionException, come descritto in Gestire le eccezioni nei plug-in, viene restituito l'errore seguente:

Codice errore: -2147220891
Messaggio di errore: codice ISV interrotto l'operazione.

Tuttavia, con questo errore, è comune che lo sviluppatore non lo intercetta correttamente e viene restituito l'errore seguente:

Codice errore: -2147220956
Messaggio di errore: si è verificato un errore imprevisto dal codice ISV.

Note

"ISV" è l'acronimo di Independent Software Vendor.

Causa

Questo errore si verifica spesso in fase di progettazione e può essere dovuto a un errore di ortografia o all'uso di maiuscole e minuscole non corrette. I valori delle chiavi fanno distinzione tra maiuscole e minuscole.

In fase di esecuzione, l'errore è spesso dovuto allo sviluppatore presupponendo 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 , DateTimeil 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 di dati all'interno di un plug-in sincrono non è supportata. Queste operazioni richiedono spesso più tempo e potrebbero causare la mancata 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: valore del nome Activity.RegardingObjectId non impostato con plug-in

Il sintomo più comune di questo problema è che il campo Informazioni in un record 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 simili a questo durante la fase PreOperation 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, questi includono Appointment, Chat, Email, Fax, Letter, PhoneCall, RecurringAppointmentMaster e tutte le 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:

  1. È possibile impostare il valore della proprietà EntityReference.Name con il valore corretto del campo del nome primario prima di impostare il valore dell'attributo di ricerca.
  2. È possibile impostare il valore di ricerca nella fase PreValidation anziché nella fase PreOperation .

Ulteriori informazioni