L’oggetto Xrm.WebApi è l’API client-side ufficiale per operare su Dataverse dalle form model-driven, dai web resource e dai controlli PCF. Rispetto a una chiamata fetch diretta all’endpoint Web API, gestisce automaticamente autenticazione, URL dell’organizzazione, versione dell’API e serializzazione: è la scelta di default in ogni contesto client.
I metodi principali
Xrm.WebApi (tramite Xrm.WebApi.online) espone cinque operazioni fondamentali:
createRecord(entityLogicalName, data)— crea un record; la Promise restituisce l’id(GUID) del nuovo record.retrieveRecord(entityLogicalName, id, options)— recupera un singolo record per GUID (o chiave alternativa), passando le opzioni OData come stringa.retrieveMultipleRecords(entityLogicalName, options, maxPageSize)— recupera un set di record via query OData o FetchXML.updateRecord(entityLogicalName, id, data)— aggiorna; invia solo i campi presenti indata(PATCH, non sovrascrive il record intero).execute(request)/executeMultiple— invoca Action, Function o messaggi custom/bound (es.WhoAmI,CalculateRollupField).
Per i lookup valgono due convenzioni chiave: in lettura il valore arriva come _nomelookup_value, in scrittura si imposta con la sintassi @odata.bind (es. "parentcustomerid@odata.bind": "/accounts(GUID)").
Query OData vs FetchXML
Le opzioni OData si concatenano in un’unica stringa che inizia con ?:
$select— colonne da restituire. Ometterlo significa over-fetching: Dataverse ritorna tutte le colonne, penalizzando performance e banda.$filter— condizioni (eq,ne,contains, operatori logiciand/or).$expand— carica le navigation property correlate in un’unica chiamata (evita round-trip aggiuntivi). Va combinato con un$selectinterno per non over-fetchare le entità espanse.$orderbye$top— ordinamento e limite di righe.
Xrm.WebApi.retrieveMultipleRecords("account",
"?$select=name,revenue&$filter=revenue gt 100000&$orderby=name asc")
FetchXML si passa a retrieveMultipleRecords con ?fetchXml=... (URL-encoded) ed è preferibile quando servono aggregazioni, join complessi tra più entità o link-entity che OData esprime a fatica. Per query relazionali semplici, OData con $expand è più leggero.
Paging
retrieveMultipleRecords restituisce solo la prima pagina. Il parametro maxPageSize (terzo argomento) fissa la dimensione pagina (default 5000, cioè il massimo per chiamata); il risultato include result.nextLink, da ripassare come options per ottenere la pagina successiva finché è valorizzato. Attenzione: usare $top disattiva il cookie di paging lato server — $top serve per un tetto assoluto di righe, non per paginare.
Online, offline, PCF
Xrm.WebApi.online— chiamate verso il server, comportamento standard.Xrm.WebApi.offline— nelle app mobile in offline mode opera sui dati sincronizzati localmente; supporta un sottoinsieme di operazioni (create/retrieve/retrieveMultiple/update/delete) e nonexecute. Va usato solo quandoXrm.WebApi.offline.isAvailableOffline(entity)conferma il supporto della tabella.- PCF — si usa
context.webAPI, nonXrm.WebApi. EsponecreateRecord,deleteRecord,retrieveRecord,retrieveMultipleRecords,updateRecord, ma nonexecute/executeMultiple, ed è disponibile solo nei contesti che lo supportano (tipicamente le model-driven app; storicamente non nelle canvas app).
Xrm.WebApi vs chiamata REST diretta
Una fetch diretta a .../api/data/v9.2/... è tecnicamente possibile ma va evitata dal contesto form: dovresti gestire manualmente token, header (OData-MaxVersion, OData-Version, Prefer), URL base e versione. La REST diretta ha senso solo in scenari fuori dal contesto client (es. codice server-side con token proprio) — ma lato plug-in/server si usa IOrganizationService, non Xrm.WebApi, che semplicemente non esiste in quel contesto.
Trappole tipiche d’esame
- Query senza
$select→ hai over-fetching. La risposta corretta impone$selectcon le sole colonne necessarie, anche dentro$expand. - Serve la seconda pagina di molti record → non aumentare
$top, ma iterare suresult.nextLink(o impostaremaxPageSizee seguire il nextLink). - Codice server-side / plug-in che deve leggere dati → non
Xrm.WebApimaIOrganizationService;Xrm.WebApivale solo client-side. - PCF che deve invocare una Action custom →
context.webAPInon haexecute: serve un approccio diverso (o chiamata dove il contesto lo consente), non aspettartiexecuteMultiple. - App mobile che deve funzionare offline → usare
Xrm.WebApi.offlineprevia verificaisAvailableOffline, ricordando che non tutte le operazioni (es.execute) sono supportate. - Impostare un lookup in create/update → usare
campo@odata.bindcon il path/entitàplurale(GUID), non il semplice GUID nel campo_value.