Problemen met Dataverse-invoegtoepassingen oplossen
Dit artikel bevat informatie over fouten die kunnen optreden tijdens het uitvoeren van invoegtoepassingen of Dataverse-fouten die betrekking hebben op invoegtoepassingen en hoe u deze kunt voorkomen of oplossen.
Fout 'Tijdconversie kan niet worden voltooid'
Foutcode: -2147220956
Foutbericht: de conversie kan niet worden voltooid omdat de opgegeven DataTime de eigenschap Type niet juist heeft ingesteld. Als de eigenschap Kind bijvoorbeeld DateTimeKind.Local is, moet de brontijdzone TimeZoneInfo.Local zijn.
Deze fout kan optreden tijdens een TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) aanroep in de invoegtoepassingscode om een DateTime
waarde in de tijdzone Santiago of Volgograd te converteren naar Coordinated Universal Time (UTC).
Deze fout wordt veroorzaakt door een bekende productbeperking en er is momenteel geen tijdelijke oplossing.
Zie Tijdzone-instellingen voor een gebruiker opgeven voor meer informatie.
Fout 'Sandbox Worker process crashed'
Foutcode: -2147204723
Foutbericht: De uitvoering van de invoegtoepassing is mislukt omdat het Sandbox Worker-proces is vastgelopen. Dit wordt meestal veroorzaakt door een fout in de invoegtoepassingscode.
Deze fout betekent gewoon dat het werkproces waarop uw invoegtoepassingscode wordt uitgevoerd, is vastgelopen. Uw invoegtoepassing kan de reden zijn voor het vastlopen, maar het kan ook een andere invoegtoepassing zijn die gelijktijdig wordt uitgevoerd voor uw organisatie. Omdat het proces is vastgelopen, kunnen we geen specifiekere informatie extraheren over waarom het is vastgelopen. Maar na het onderzoeken van gegevens uit de crashdumps na het feit, hebben we vastgesteld dat deze fout meestal optreedt vanwege een van de vier redenen:
- Niet-verwerkte uitzondering in de invoegtoepassing
- Threads gebruiken om in de wachtrij te plaatsen, werken zonder try/catch in thread delegate
- Stack Overflow-fout in de invoegtoepassing
- Werkproces bereikt de geheugenlimiet
Niet-verwerkte uitzondering in de invoegtoepassing
Wanneer u een invoegtoepassing schrijft, moet u proberen te voorspellen welke bewerkingen kunnen mislukken en in een try-catch-blok kunnen verpakken. Wanneer er een fout optreedt, moet u de klasse gebruiken om de InvalidPluginExecutionException bewerking correct te beëindigen met een fout die zinvol is voor de gebruiker.
Zie Uitzonderingen in invoegtoepassingen verwerken voor meer informatie.
Een veelvoorkomend scenario voor deze uitzondering is wanneer u de methode HttpClient.SendAsync of HttpClient.GetAsync gebruikt. Deze HttpClient-methoden zijn asynchrone bewerkingen die een taak retourneren. Als u wilt werken in een invoegtoepassing waarin code synchroon moet zijn, kunnen personen de taak-TResult>< gebruiken. Resultaateigenschap. Wanneer er een fout optreedt, Result
wordt een AggregateException geretourneerd. Een AggregateException
consolideert meerdere fouten in één uitzondering, wat moeilijk te verwerken kan zijn. Een beter ontwerp is het gebruik van Taak-TResult<>. GetAwaiter().GetResult() omdat de resultaten worden doorgegeven als de specifieke fout die de fout heeft veroorzaakt.
In het volgende voorbeeld ziet u de juiste manier om de uitzondering en een uitgaande aanroep te beheren met behulp van de methode HttpClient.GetAsync . Deze invoegtoepassing probeert de antwoordtekst voor een URI-set op te halen in de niet-beveiligde configuratie voor een stap die voor deze invoegtoepassing is geregistreerd.
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);
}
}
}
}
Threads gebruiken om in de wachtrij te plaatsen, werken zonder try/catch in thread delegate
Gebruik geen parallelle uitvoeringspatronen in invoegtoepassingen. Dit antipatroon wordt beschreven in het best practice-artikel: Gebruik geen parallelle uitvoering binnen invoegtoepassingen en werkstroomactiviteiten. Het gebruik van deze patronen kan problemen veroorzaken bij het beheren van de transactie in een synchrone invoegtoepassing. Een andere reden om deze patronen niet te gebruiken, is dat werk dat buiten een blok in een try
/catch
threaddelegatie wordt uitgevoerd, het werkproces kan vastlopen.
Belangrijk
Wanneer het werkproces vastloopt, wordt de uitvoering van uw invoegtoepassing en andere invoegtoepassingen die momenteel in dat proces worden uitgevoerd, beëindigd. Dit omvat invoegtoepassingen die u niet bezit of onderhoudt.
Application Insights voor de redding
In het verleden was het verkrijgen van de stacktracering of andere uitvoeringsinformatie voor niet-verwerkte invoegtoepassinguitzondering van het vastgelopen werkproces onmogelijk. Dataverse biedt nu echter ondersteuning voor het uitvoeren van logboekregistratiefouten in Application Insights. Als u deze functie wilt inschakelen, kunt u Application Insights koppelen aan de omgeving waarin uw invoegtoepassing is geregistreerd. Zodra de koppeling is gekoppeld, treedt de logboekregistratie van invoegtoepassingen automatisch op.
Zie Gegevens exporteren naar Application Insights voor meer informatie.
Nadat een Application Insights-omgeving is gekoppeld, zijn de volgende gegevens van een werkprocescrash beschikbaar om het probleem op te lossen.
Ga als volgt te werk om naar het crashrapport in Application Insights te gaan:
- Koppel Application Insights aan uw omgeving.
- Wacht totdat een invoegtoepassingsuitzondering resulteert in de crashfout van het werkproces.
- Navigeer in het Power Platform-beheercentrum naar Application Insights.
- Selecteer fouten in het linkerdeelvenster op de pagina Application Insights.
- Selecteer uitzonderingen op de pagina Fouten.
- Selecteer microsoft.PowerPlatform.Dataverse.Plugin.Plugin.Plugin.PluginWorkerCrashException onder Uitzonderingsprobleem-id.
- Selecteer PluginWorkerCrashException aan de rechterkant van de pagina onder Overall. U ziet nu de details van alle vastgelegde crashuitzondering van het werkproces.
- Zoek en selecteer de gewenste uitzondering in het linkerdeelvenster en het rapport met uitzonderingsgegevens wordt aan de rechterkant van de pagina weergegeven (zie de voorgaande schermopname voor een voorbeeld).
- Als u toegang wilt krijgen tot de stacktracering, vouwt u CrashDetails uit in het rapport.
Stack-overloopfout in de invoegtoepassing
Dit type fout treedt het vaakst op nadat u enkele wijzigingen in uw invoegtoepassingscode hebt aangebracht. Sommige mensen gebruiken hun eigen set basisklassen om hun ontwikkelervaring te stroomlijnen. Soms zijn deze fouten afkomstig van wijzigingen in die basisklassen waarvoor een bepaalde invoegtoepassing afhankelijk is.
Een recursieve oproep zonder beëindigingsvoorwaarde of een beëindigingsvoorwaarde, die niet alle scenario's omvat, kan deze fout veroorzaken. Zie StackOverflowException Class > Opmerkingen voor meer informatie.
Controleer alle codewijzigingen die onlangs zijn toegepast voor de invoegtoepassing en eventuele andere code waarop de invoegtoepassingscode afhankelijk is.
Voorbeeld
De volgende invoegtoepassingscode zorgt voor een StackOverflowException
recursieve aanroep zonder limieten. Ondanks het gebruik van de tracering en het vastleggen van de fout, worden de tracering en de fout niet geretourneerd omdat het werkproces dat ze zou verwerken, werd beëindigd.
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 een synchrone invoegtoepassingsstap retourneert de eerder getoonde invoegtoepassingscode de volgende fout in de web-API wanneer de aanvraag is geconfigureerd om aanvullende details met fouten op te nemen.
{
"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"
}
}
Hieronder ziet u hoe deze fout wordt vastgelegd in de tracelog van de invoegtoepassing:
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>
Werkproces bereikt de geheugenlimiet
Elk werkproces heeft een beperkte hoeveelheid geheugen. Er zijn omstandigheden waarin meerdere gelijktijdige bewerkingen met grote hoeveelheden gegevens het beschikbare geheugen kunnen overschrijden en de proceswerkrol vastloopt.
RetrieveMultiple met bestandsgegevens
Het veelvoorkomende scenario is in dit geval wanneer een invoegtoepassing wordt uitgevoerd voor een RetrieveMultiple
bewerking waarin de aanvraag bestandsgegevens bevat. Bijvoorbeeld bij het ophalen van e-mailberichten die bestandsbijlagen bevatten. De hoeveelheid gegevens die in een query als deze kan worden geretourneerd, is onvoorspelbaar omdat e-mail mogelijk te maken heeft met een willekeurig aantal bestandsbijlagen en de bijlagen kunnen variëren in grootte.
Wanneer meerdere aanvragen van een vergelijkbare aard gelijktijdig worden uitgevoerd, wordt de hoeveelheid geheugen die nodig is, groot. Als de hoeveelheid geheugen de limiet overschrijdt, loopt het proces vast. De sleutel om deze situatie te voorkomen, is het beperken van RetrieveMultiple
query's die entiteiten met gerelateerde bestandsbijlagen bevatten. Haal de records op met behulp van RetrieveMultiple
, maar haal indien nodig gerelateerde bestanden op met behulp van afzonderlijke Retrieve
bewerkingen.
Geheugenlekken
Een minder gangbaar scenario is waarbij de code in de invoegtoepassing geheugen lekt. Deze situatie kan optreden wanneer de invoegtoepassing niet is geschreven als staatloos, wat een andere best practice is. Zie Implementaties van invoegtoepassingen ontwikkelen als staatloos voor meer informatie. Wanneer de invoegtoepassing niet staatloos is en er wordt geprobeerd voortdurend gegevens toe te voegen aan een stateful eigenschap zoals een matrix, neemt de hoeveelheid gegevens toe tot het punt waar alle beschikbare geheugen wordt gebruikt.
Transactiefouten
Er zijn twee veelvoorkomende typen fouten met betrekking tot transacties:
Foutcode: -2146893812
Foutbericht: ISV-code heeft het aantal geopende transacties verminderd. Aangepaste invoegtoepassingen mogen geen uitzonderingen van OrganizationService-aanroepen ondervangen en doorgaan met verwerken.
Foutcode: -2147220911
Foutbericht: er is geen actieve transactie. Deze fout wordt meestal veroorzaakt door aangepaste invoegtoepassingen die fouten van serviceoproepen negeren en doorgaan met verwerken.
Notitie
De belangrijkste fout is het laatst toegevoegd. Deze moet onmiddellijk plaatsvinden en in de context van de invoegtoepassing die het probleem bevat. De onderste fout kan nog steeds optreden in verschillende omstandigheden, meestal met aangepaste werkstroomactiviteiten. Dit kan worden veroorzaakt door problemen in een andere invoegtoepassing.
Wanneer er een fout optreedt met betrekking tot een gegevensbewerking binnen een synchrone invoegtoepassing, wordt de transactie voor de hele bewerking beëindigd.
Zie Het schaalbare aanpassingsontwerp in Microsoft Dataverse voor meer informatie.
Een veelvoorkomende oorzaak is dat een ontwikkelaar denkt dat ze kunnen proberen een bewerking uit te voeren die kan slagen, zodat ze die bewerking in een try
/catch
blok verpakken en proberen de fout in te slikken wanneer deze mislukt.
Hoewel dit patroon mogelijk werkt voor een clienttoepassing, leidt elke fout bij het uitvoeren van een gegevensbewerking tot het terugdraaien van de hele transactie. Je kunt de fout niet inslikken, dus je moet ervoor zorgen dat je altijd een InvalidPluginExecutionException.
Fout 'Sql-fout: time-out van uitvoering verlopen'
Foutcode: -2147204783
Foutbericht: Sql-fout: 'Time-out van uitvoering is verlopen. De time-outperiode die is verstreken voordat de bewerking is voltooid of de server reageert niet.".
Oorzaak
Er zijn verschillende redenen waarom een SQL-time-outfout kan optreden. Drie van deze worden hier beschreven:
Blokkering
De meest voorkomende oorzaak van een SQL-time-outfout is dat de bewerking wacht op resources die worden geblokkeerd door een andere SQL-transactie. De fout is het resultaat van dataverse die de integriteit van de gegevens beschermt en van langlopende aanvragen die van invloed zijn op de prestaties voor gebruikers.
Blokkeren kan worden veroorzaakt door andere gelijktijdige bewerkingen. Uw code werkt mogelijk prima geïsoleerd in een testomgeving en is nog steeds vatbaar voor omstandigheden die alleen optreden wanneer meerdere gebruikers de logica in uw invoegtoepassing initiëren.
Bij het schrijven van invoegtoepassingen is het essentieel om te begrijpen hoe u aanpassingen ontwerpt die schaalbaar zijn. Zie Het schaalbare aanpassingsontwerp in Dataverse voor meer informatie.
Trapsgewijze bewerkingen
Bepaalde acties die u in uw invoegtoepassing uitvoert, zoals het toewijzen of verwijderen van een record, kunnen trapsgewijze bewerkingen voor gerelateerde records initiëren. Deze acties kunnen vergrendelingen toepassen op gerelateerde records, waardoor volgende gegevensbewerkingen worden geblokkeerd, wat op zijn beurt kan leiden tot een SQL-time-out.
Houd rekening met de mogelijke impact van deze trapsgewijze bewerkingen op gegevensbewerkingen in uw invoegtoepassing. Zie Tabelrelatiegedrag voor meer informatie.
Omdat dit gedrag anders kan worden geconfigureerd tussen omgevingen, kan het gedrag moeilijk te reproduceren zijn, tenzij de omgevingen op dezelfde manier zijn geconfigureerd.
Indexen voor nieuwe tabellen
Als de invoegtoepassing bewerkingen uitvoert met behulp van een tabel of kolom die onlangs is gemaakt, kunnen sommige Azure SQL-mogelijkheden voor het beheren van indexen na enkele dagen een verschil maken.
Fouten vanwege gebruikersbevoegdheden
In een clienttoepassing kunt u opdrachten uitschakelen die gebruikers niet mogen uitvoeren. Binnen een invoegtoepassing hebt u deze mogelijkheid niet. Uw code bevat mogelijk enkele automatiseringen die de aanroepende gebruiker niet heeft om uit te voeren.
U kunt de invoegtoepassing registreren die moet worden uitgevoerd in de context van een gebruiker waarvan bekend is dat deze over de juiste bevoegdheden beschikt door de waarde Uitvoeren in de context van de gebruiker in te stellen op die gebruiker. U kunt de bewerking ook uitvoeren door een andere gebruiker te imiteren. Zie voor meer informatie:
Fout bij het uitvoeren in de context van een uitgeschakelde gebruiker
Wanneer een invoegtoepassing wordt uitgevoerd in de context van een uitgeschakelde gebruiker, wordt de volgende fout geretourneerd:
Foutbericht: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: de gebruiker met SystemUserId=<User-ID> in OrganizationContext=<Context> is uitgeschakeld. Uitgeschakelde gebruikers hebben geen toegang tot het systeem. Overweeg deze gebruiker in te schakelen. Gebruikers worden ook uitgeschakeld als er geen licentie aan hen is toegewezen.
Als u deze fout wilt oplossen, kunt u een query uitvoeren om de stappen te vinden die zijn geregistreerd bij de uitgeschakelde gebruiker, evenals de bijbehorende invoegtoepassing en SdkMessage
details.
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
Fout 'Berichtgrootte overschreden bij het verzenden van context naar Sandbox'
Foutcode: -2147220970
Foutbericht: de berichtgrootte is overschreden bij het verzenden van context naar Sandbox. Berichtgrootte: ### Mb
Deze fout treedt op wanneer een nettolading van een bericht groter is dan 116,85 MB en een invoegtoepassing is geregistreerd voor het bericht. Het foutbericht bevat de grootte van de nettolading die deze fout heeft veroorzaakt.
De limiet zorgt ervoor dat gebruikers met toepassingen elkaar niet kunnen verstoren op basis van resourcebeperkingen. De limiet helpt een niveau van beveiliging te bieden tegen ongebruikelijk grote nettoladingen van berichten die de beschikbaarheid en prestatiekenmerken van het Dataverse-platform bedreigen.
116,85 MB is groot genoeg om deze zaak zelden tegen te komen. De meest waarschijnlijke situatie waarin dit geval kan optreden, is wanneer u een record ophaalt met meerdere gerelateerde records die grote binaire bestanden bevatten.
Als u deze fout krijgt, kunt u het volgende doen:
- Verwijder de invoegtoepassing voor het bericht. Als er geen invoegtoepassingen zijn geregistreerd voor het bericht, wordt de bewerking zonder een fout voltooid.
- Als de fout optreedt in een aangepaste client, kunt u de code wijzigen zodat er niet wordt geprobeerd het werk in één bewerking uit te voeren. Schrijf in plaats daarvan code om de gegevens in kleinere delen op te halen.
Fout 'De opgegeven sleutel was niet aanwezig in de woordenlijst'
Dataverse maakt vaak gebruik van klassen die zijn afgeleid van de abstracte DataCollection<TKey,TValue> klasse die een verzameling sleutels en waarden vertegenwoordigt. Met invoegtoepassingen is de IExecutionContexteigenschap .InputParameters bijvoorbeeld een ParameterCollection afgeleide van de DataCollection<TKey,TValue> klasse. Deze klassen zijn in feite woordenlijstobjecten waarbij u toegang hebt tot een specifieke waarde met behulp van de sleutelnaam.
Foutcodes
Deze fout treedt op wanneer de sleutelwaarde in de code niet bestaat in de verzameling. Het resultaat is een runtimefout in plaats van een platformfout. Wanneer deze fout optreedt in een invoegtoepassing, is de foutcode afhankelijk van of de fout is opgetreden.
Als de ontwikkelaar de uitzondering heeft gedetecteerd en geretourneerd InvalidPluginExecutionException, zoals beschreven in Invoegtoepassingen verwerken van uitzonderingen, wordt de volgende fout geretourneerd:
Foutcode: -2147220891
Foutbericht: ISV-code heeft de bewerking afgebroken.
Met deze fout is het echter gebruikelijk dat de ontwikkelaar deze niet goed ondervangt en dat de volgende fout wordt geretourneerd:
Foutcode: -2147220956
Foutbericht: Er is een onverwachte fout opgetreden in de ISV-code.
Notitie
ISV staat voor Independent Software Vendor.
Oorzaak
Deze fout treedt vaak op tijdens het ontwerp en kan worden veroorzaakt door een spelfout of het gebruik van de onjuiste behuizing. De sleutelwaarden zijn hoofdlettergevoelig.
Tijdens runtime wordt de fout vaak veroorzaakt door de ontwikkelaar, ervan uitgaande dat de waarde aanwezig is wanneer deze niet aanwezig is. In een invoegtoepassing die is geregistreerd voor de update van een tabel, worden bijvoorbeeld alleen de gewijzigde waarden opgenomen in de Entityverzameling .Attributes
Oplossing
Als u deze fout wilt oplossen, moet u controleren of de sleutel bestaat voordat u deze probeert te gebruiken voor toegang tot een waarde.
Wanneer u bijvoorbeeld een tabelkolom opent, kunt u de Entitymethode .Contains(String) gebruiken om te controleren of een kolom in een tabel bestaat, zoals wordt weergegeven in de volgende code.
// 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"];
}
Sommige ontwikkelaars gebruiken de Entitymethode .GetAttributeValue<T>(String) om deze fout te voorkomen bij het openen van een tabelkolom. Deze methode retourneert de standaardwaarde van het type als de kolom niet bestaat. Als de standaardwaarde null is, werkt deze methode zoals verwacht. Maar als de standaardwaarde geen null retourneert, zoals bij een DateTime
, is 1/1/0001 00:00
de geretourneerde waarde in plaats van null.
Fout 'U kunt een transactie niet starten met een ander isolatieniveau dan al is ingesteld op de huidige transactie'
Foutcode: -2147220989
Foutbericht: U kunt een transactie met een ander isolatieniveau niet starten dan al is ingesteld op de huidige transactie
Invoegtoepassingen zijn bedoeld ter ondersteuning van bedrijfslogica. Het wijzigen van een deel van het gegevensschema in een synchrone invoegtoepassing wordt niet ondersteund. Deze bewerkingen duren vaak langer en kunnen ertoe leiden dat metagegevens in de cache die door toepassingen worden gebruikt, niet meer worden gesynchroniseerd. Deze bewerkingen kunnen echter worden uitgevoerd in een invoegtoepassingsstap die is geregistreerd om asynchroon uit te voeren.
Bekend probleem: Activity.RegardingObjectId name value not set with plug-in
Het meest voorkomende symptoom van dit probleem is dat het veld Betreffende in een activiteitsrecord wordt weergegeven (No Name)
in plaats van de waarde van het kenmerk primaire naam.
In een invoegtoepassing kunt u opzoekkenmerken instellen met een EntityReference-waarde . De eigenschap EntityReference.Name is niet vereist. Normaal gesproken hoeft u deze niet op te nemen bij het instellen van een opzoekkenmerkwaarde, omdat dataverse deze instelt. U moet waarden als deze instellen tijdens de PreOperation-fase van de gebeurtenispijplijn. Zie Pijplijn voor gebeurtenisuitvoering voor meer informatie.
De uitzondering op deze regel is wanneer u de lookup ActivityPointer.RegardingObjectId instelt. Alle entiteitstypen die zijn afgeleid van ActivityPointer
deze zoekactie nemen over. Deze omvatten standaard Afspraak, Chat, E-mail, Fax, Brief, PhoneCall, RecurringAppointmentMaster en aangepaste tabellen die zijn gemaakt als activiteitstypen. Zie Activiteitentabellen voor meer informatie.
Als u deze waarde instelt in de fase PreOperation , wordt de naamwaarde niet toegevoegd door Dataverse. De waarde is null en de opgemaakte waarde die deze waarde moet bevatten, is niet aanwezig wanneer u de record ophaalt.
Tijdelijke oplossing
Er zijn twee manieren om dit probleem te omzeilen:
- U kunt de waarde van de eigenschap EntityReference.Name instellen met de juiste primaire naamveldwaarde voordat u de waarde van het opzoekkenmerk instelt.
- U kunt de opzoekwaarde instellen in de fase PreValidation in plaats van in de fase PreOperation.