Utiliser FetchXML avec l’API Web
FetchXML est un langage de requête propriétaire qui peut récupérer et agréger des données à l’aide de l’API Web et du SDK .NET. Plus d’informations : Utilisez FetchXML pour interroger des données.
Notes
Contrairement aux requêtes qui utilisent la syntaxe OData, FetchXML les requêtes ne renvoient pas de propriétés avec null
valeurs.
Vous pouvez composer une FetchXML requête pour une table spécifique. Ensuite, encodez l’URL du XML et utilisez le paramètre de chaîne de requête fetchXml
pour le transmettre à l’ensemble d’entités.
Par exemple, l’entité suivante FetchXML a account
comme entité :
<fetch mapping='logical'>
<entity name='account'>
<attribute name='accountid'/>
<attribute name='name'/>
<attribute name='accountnumber'/>
</entity>
</fetch>
Ceci FetchXML a la valeur codée en URL suivante :
%3Cfetch%20mapping%3D%27logical%27%3E%3Centity%20name%3D%27account%27%3E%3Cattribute%20name%3D%27accountid%27%2F%3E%3Cattribute%20name%3D%27name%27%2F%3E%3Cattribute%20name%3D%27accountnumber%27%2F%3E%3C%2Fentity%3E%3C%2Ffetch%3E
La plupart des langages de programmation proposent une fonction pour encoder une chaîne au format URL.
- Dans JavaScript, vous pouvez utiliser la fonction encodeURI.
- Dans .NET, vous pouvez utiliser la méthode System.NET.WebUtility.UrlEncode(String)
Vous devez encoder au format URL toute requête que vous envoyez à un service Web RESTful. Si vous collez une URL dans la barre d’adresse de votre navigateur, il doit encoder automatiquement l’adresse au format URL.
L’exemple suivant montre une GET
requête utilisant la précédente FetchXML avec le chemin d’accès de l’ensemble d’entités pour accounts
. Il transmet le XML encodé à l’aide de ce paramètre : ?fetchXml=
Demande :
GET [Organization URI]/api/data/v9.2/accounts?fetchXml=%3Cfetch%20mapping%3D%27logical%27%3E%3Centity%20name%3D%27account%27%3E%3Cattribute%20name%3D%27accountid%27%2F%3E%3Cattribute%20name%3D%27name%27%2F%3E%3Cattribute%20name%3D%27accountnumber%27%2F%3E%3C%2Fentity%3E%3C%2Ffetch%3E HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Réponse :
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"@odata.context":"[Organization URI]/api/data/v9.2/$metadata#accounts(accountid,name)","value":[
{
"@odata.etag":"W/\"506678\"",
"accountid":"89390c24-9c72-e511-80d4-00155d2a68d1",
"name":"Fourth Coffee (sample)",
"accountnumber":"1234",
},{
"@odata.etag":"W/\"502172\"",
"accountid":"8b390c24-9c72-e511-80d4-00155d2a68d1",
"name":"Litware, Inc. (sample)"
},{
"@odata.etag":"W/\"502174\"",
"accountid":"8d390c24-9c72-e511-80d4-00155d2a68d1",
"name":"Adventure Works (sample)"
},{
"@odata.etag":"W/\"506705\"",
"accountid":"8f390c24-9c72-e511-80d4-00155d2a68d1",
"name":"Fabrikam, Inc. (sample)"
}
]
}
Rappelez-vous que les propriétés avec des valeurs nulles ne sont pas incluses dans les résultats renvoyés à l’aide de FetchXML. Dans cet exemple ci-dessus, seul le premier enregistrement renvoyé a une valeur accountnumber
.
Pagination avec FetchXML
Avec FetchXML, vous pouvez appliquer une pagination simple en définissant les page
et count
attributs de l’élément fetch
. Par exemple, pour définir une requête pour les comptes et limiter le nombre d’entités à 2 et pour retourner uniquement la première page, utilisez la valeur fetchXML suivante :
<fetch mapping="logical"
page="1"
count="2">
<entity name="account">
<attribute name="accountid" />
<attribute name="name" />
<attribute name="industrycode" />
<order attribute="name" />
</entity>
</fetch>
Pagination de grands ensembles de résultats
Lorsque vous travaillez avec de grands ensembles de résultats qui atteignent la limite de pagination de 5 000, l’utilisation de cookies de pagination avec la requête permet d’améliorer les performances. Demandez un cookie de pagination comme annotation. Utilisez l’en-tête de demande prefer: odata.include-annotations
pour utiliser ou inclure Microsoft.Dynamics.CRM.fetchxmlpagingcookie
, et une annotation @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
est renvoyée avec le résultat.
La série de requêtes suivante FetchXML montre l’utilisation de cookies de pagination. Cet exemple utilise une petite valeur count
(3) par souci de concision. Normalement, vous n’utiliseriez pas de cookies de pagination pour des pages aussi petites.
<fetch page='1'
count='3'
paging-cookie=''
mapping='logical'
output-format='xml-platform'
version='1.0'
distinct='false'>
<entity name ='contact'>
<attribute name ='fullname' />
<attribute name ='jobtitle' />
<attribute name ='annualincome' />
<order descending ='true'
attribute='fullname' />
<filter type ='and'>
<condition value ='%(sample)%'
attribute='fullname'
operator='like' />
<condition value ='18717e9c-643f-ed11-9db0-002248225e95'
attribute='parentcustomerid'
operator='eq' />
</filter>
</entity>
</fetch>
Première page
Envoyez la première page avec l’ensemble de valeurs page
sur '1'
. Utilisez l’en-tête de demande Prefer: odata.include-annotations="*"
pour vous assurer que les annotations nécessaires dans la réponse sont renvoyées.
Demande :
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch+page%3D%221%22+count%3D%223%22+mapping%3D%22logical%22+output-format%3D%22xml-platform%22+version%3D%221.0%22+distinct%3D%22false%22%3E%0D%0A++%3Centity+name%3D%22contact%22%3E%0D%0A++++%3Cattribute+name%3D%22fullname%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22jobtitle%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22annualincome%22+%2F%3E%0D%0A++++%3Corder+descending%3D%22true%22+attribute%3D%22fullname%22+%2F%3E%0D%0A++++%3Cfilter+type%3D%22and%22%3E%0D%0A++++++%3Ccondition+value%3D%22%25(sample)%25%22+attribute%3D%22fullname%22+operator%3D%22like%22+%2F%3E%0D%0A++++++%3Ccondition+value%3D%2218717e9c-643f-ed11-9db0-002248225e95%22+attribute%3D%22parentcustomerid%22+operator%3D%22eq%22+%2F%3E%0D%0A++++%3C%2Ffilter%3E%0D%0A++%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E&$count=true HTTP/1.1
Prefer: odata.include-annotations="*"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Réponse :
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.include-annotations="*"
{
"@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,annualincome,_transactioncurrencyid_value,transactioncurrencyid,contactid,transactioncurrencyid())",
"@odata.count": 8,
"@Microsoft.Dynamics.CRM.totalrecordcount": 8,
"@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded": false,
"@Microsoft.Dynamics.CRM.globalmetadataversion": "74343461",
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": "<cookie pagenumber=\"2\" pagingcookie=\"%253ccookie%2520page%253d%25221%2522%253e%253cfullname%2520last%253d%2522Robert%2520Lyon%2520%2528sample%2529%2522%2520first%253d%2522Susanna%2520Stubberod%2520%2528sample%2529%2522%2520%252f%253e%253ccontactid%2520last%253d%2522%257b30717E9C-643F-ED11-9DB0-002248225E95%257d%2522%2520first%253d%2522%257b20717E9C-643F-ED11-9DB0-002248225E95%257d%2522%2520%252f%253e%253c%252fcookie%253e\" istracking=\"False\" />",
"@Microsoft.Dynamics.CRM.morerecords": true,
"value": [
{
"@odata.etag": "W/\"74359676\"",
"fullname": "Susanna Stubberod (sample)",
"jobtitle": "Senior Purchaser",
"annualincome@OData.Community.Display.V1.FormattedValue": "$52,000.00",
"annualincome": 52000.0,
"contactid": "20717e9c-643f-ed11-9db0-002248225e95"
},
{
"@odata.etag": "W/\"74359706\"",
"fullname": "Scott Konersmann (sample)",
"jobtitle": "Accounts Manager",
"annualincome@OData.Community.Display.V1.FormattedValue": "$38,000.00",
"annualincome": 38000.0,
"contactid": "2c717e9c-643f-ed11-9db0-002248225e95"
},
{
"@odata.etag": "W/\"74359716\"",
"fullname": "Robert Lyon (sample)",
"jobtitle": "Senior Technician",
"annualincome@OData.Community.Display.V1.FormattedValue": "$78,000.00",
"annualincome": 78000.0,
"contactid": "30717e9c-643f-ed11-9db0-002248225e95"
}
]
}
Dans la réponse, la valeur d’annotation @Microsoft.Dynamics.CRM.morerecords
indique qu’il existe d’autres enregistrements correspondant aux critères.
La valeur d’annotation @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
fournit les informations de pagination sur l’enregistrement renvoyé. La valeur @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
est un document XML. Vous devez utiliser la valeur d’attribut pagingcookie
de ce document dans la prochaine requête.
La valeur pour l’attribut pagingcookie
est encodée en URL à deux reprises. La valeur encodée ressemble à ce qui suit :
<cookie page="1"><fullname last="Robert Lyon (sample)" first="Susanna Stubberod (sample)" /><contactid last="{30717E9C-643F-ED11-9DB0-002248225E95}" first="{20717E9C-643F-ED11-9DB0-002248225E95}" /></cookie>
Pages suivantes
Dans toutes les requêtes suivantes où la valeur d’annotation @Microsoft.Dynamics.CRM.morerecords
de la page précédente indique qu’il existe plus d’enregistrements, vous devez :
Incrémenter la valeur d’attribut
page
de l’élémentfetch
.décoder l’URL de la valeur d’attribut
pagingcookie
deux fois.encoder en XML la valeur d’attribut
pagingcookie
décodée et la définir comme la valeur d’un attributpaging-cookie
sur l’élémentfetch
.Selon la technologie utilisée, vous devrez peut-être encoder explicitement en XML la valeur. Dans .NET, cela peut être fait pour vous lorsque vous définissez la valeur XML sur un attribut d’un autre élément XML.
Encodez URL toute la valeur FetchXml comme vous l’aviez fait dans la première requête.
Dans la requête suivante, le FetchXML ressemble à ceci avant d’être codé en URL :
<fetch page="2" count="3" mapping="logical" output-format="xml-platform" version="1.0" distinct="false" paging-cookie="<cookie page="1"><fullname last="Robert Lyon (sample)" first="Susanna Stubberod (sample)" /><contactid last="{30717E9C-643F-ED11-9DB0-002248225E95}" first="{20717E9C-643F-ED11-9DB0-002248225E95}" /></cookie>">
<entity name="contact">
<attribute name="fullname" />
<attribute name="jobtitle" />
<attribute name="annualincome" />
<order descending="true" attribute="fullname" />
<filter type="and">
<condition value="%(sample)%" attribute="fullname" operator="like" />
<condition value="18717e9c-643f-ed11-9db0-002248225e95" attribute="parentcustomerid" operator="eq" />
</filter>
</entity>
</fetch>
Demande :
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch+page%3D%222%22+count%3D%223%22+mapping%3D%22logical%22+output-format%3D%22xml-platform%22+version%3D%221.0%22+distinct%3D%22false%22+paging-cookie%3D%22%26lt%3Bcookie+page%3D%26quot%3B1%26quot%3B%26gt%3B%26lt%3Bfullname+last%3D%26quot%3BRobert+Lyon+(sample)%26quot%3B+first%3D%26quot%3BSusanna+Stubberod+(sample)%26quot%3B+%2F%26gt%3B%26lt%3Bcontactid+last%3D%26quot%3B%7B30717E9C-643F-ED11-9DB0-002248225E95%7D%26quot%3B+first%3D%26quot%3B%7B20717E9C-643F-ED11-9DB0-002248225E95%7D%26quot%3B+%2F%26gt%3B%26lt%3B%2Fcookie%26gt%3B%22%3E%0D%0A++%3Centity+name%3D%22contact%22%3E%0D%0A++++%3Cattribute+name%3D%22fullname%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22jobtitle%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22annualincome%22+%2F%3E%0D%0A++++%3Corder+descending%3D%22true%22+attribute%3D%22fullname%22+%2F%3E%0D%0A++++%3Cfilter+type%3D%22and%22%3E%0D%0A++++++%3Ccondition+value%3D%22%25(sample)%25%22+attribute%3D%22fullname%22+operator%3D%22like%22+%2F%3E%0D%0A++++++%3Ccondition+value%3D%2218717e9c-643f-ed11-9db0-002248225e95%22+attribute%3D%22parentcustomerid%22+operator%3D%22eq%22+%2F%3E%0D%0A++++%3C%2Ffilter%3E%0D%0A++%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E&$count=true HTTP/1.1
Prefer: odata.include-annotations="*"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Réponse :
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.include-annotations="*"
{
"@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,annualincome,_transactioncurrencyid_value,transactioncurrencyid,contactid,transactioncurrencyid())",
"@odata.count": 8,
"@Microsoft.Dynamics.CRM.totalrecordcount": 8,
"@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded": false,
"@Microsoft.Dynamics.CRM.globalmetadataversion": "74343461",
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": "<cookie pagenumber=\"2\" pagingcookie=\"%253ccookie%2520page%253d%25222%2522%253e%253cfullname%2520last%253d%2522Nancy%2520Anderson%2520%2528sample%2529%2522%2520first%253d%2522Rene%2520Valdes%2520%2528sample%2529%2522%2520%252f%253e%253ccontactid%2520last%253d%2522%257b24717E9C-643F-ED11-9DB0-002248225E95%257d%2522%2520first%253d%2522%257b38717E9C-643F-ED11-9DB0-002248225E95%257d%2522%2520%252f%253e%253c%252fcookie%253e\" istracking=\"False\" />",
"@Microsoft.Dynamics.CRM.morerecords": true,
"value": [
{
"@odata.etag": "W/\"74359736\"",
"fullname": "Rene Valdes (sample)",
"jobtitle": "Data Analyst III",
"annualincome@OData.Community.Display.V1.FormattedValue": "$86,000.00",
"annualincome": 86000.0,
"contactid": "38717e9c-643f-ed11-9db0-002248225e95"
},
{
"@odata.etag": "W/\"74359726\"",
"fullname": "Paul Cannon (sample)",
"jobtitle": "Ski Instructor",
"annualincome@OData.Community.Display.V1.FormattedValue": "$68,500.00",
"annualincome": 68500.0,
"contactid": "34717e9c-643f-ed11-9db0-002248225e95"
},
{
"@odata.etag": "W/\"74359686\"",
"fullname": "Nancy Anderson (sample)",
"jobtitle": "Activities Manager",
"annualincome@OData.Community.Display.V1.FormattedValue": "$55,500.00",
"annualincome": 55500.0,
"contactid": "24717e9c-643f-ed11-9db0-002248225e95"
}
]
}
Dernière page
Sur la dernière page, les annotations @Microsoft.Dynamics.CRM.morerecords
et @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
ne sont pas incluses dans la réponse.
Demande :
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch+page%3D%223%22+count%3D%223%22+mapping%3D%22logical%22+output-format%3D%22xml-platform%22+version%3D%221.0%22+distinct%3D%22false%22+paging-cookie%3D%22%26lt%3Bcookie+page%3D%26quot%3B2%26quot%3B%26gt%3B%26lt%3Bfullname+last%3D%26quot%3BNancy+Anderson+(sample)%26quot%3B+first%3D%26quot%3BRene+Valdes+(sample)%26quot%3B+%2F%26gt%3B%26lt%3Bcontactid+last%3D%26quot%3B%7B24717E9C-643F-ED11-9DB0-002248225E95%7D%26quot%3B+first%3D%26quot%3B%7B38717E9C-643F-ED11-9DB0-002248225E95%7D%26quot%3B+%2F%26gt%3B%26lt%3B%2Fcookie%26gt%3B%22%3E%0D%0A++%3Centity+name%3D%22contact%22%3E%0D%0A++++%3Cattribute+name%3D%22fullname%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22jobtitle%22+%2F%3E%0D%0A++++%3Cattribute+name%3D%22annualincome%22+%2F%3E%0D%0A++++%3Corder+descending%3D%22true%22+attribute%3D%22fullname%22+%2F%3E%0D%0A++++%3Cfilter+type%3D%22and%22%3E%0D%0A++++++%3Ccondition+value%3D%22%25(sample)%25%22+attribute%3D%22fullname%22+operator%3D%22like%22+%2F%3E%0D%0A++++++%3Ccondition+value%3D%2218717e9c-643f-ed11-9db0-002248225e95%22+attribute%3D%22parentcustomerid%22+operator%3D%22eq%22+%2F%3E%0D%0A++++%3C%2Ffilter%3E%0D%0A++%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E&$count=true HTTP/1.1
Prefer: odata.include-annotations="*"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Réponse :
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.include-annotations="*"
{
"@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,annualincome,_transactioncurrencyid_value,transactioncurrencyid,contactid,transactioncurrencyid())",
"@odata.count": 8,
"@Microsoft.Dynamics.CRM.totalrecordcount": 8,
"@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded": false,
"@Microsoft.Dynamics.CRM.globalmetadataversion": "74343461",
"value": [
{
"@odata.etag": "W/\"74359696\"",
"fullname": "Maria Cambell (sample)",
"jobtitle": "Accounts Manager",
"annualincome@OData.Community.Display.V1.FormattedValue": "$31,000.00",
"annualincome": 31000.0,
"contactid": "28717e9c-643f-ed11-9db0-002248225e95"
},
{
"@odata.etag": "W/\"74359746\"",
"fullname": "Jim Glynn (sample)",
"jobtitle": "Senior International Sales Manager",
"annualincome@OData.Community.Display.V1.FormattedValue": "$81,400.00",
"annualincome": 81400.0,
"contactid": "3c717e9c-643f-ed11-9db0-002248225e95"
}
]
}
Utiliser FetchXML dans une requête groupée
La longueur d’une URL dans une requête GET
est limitée à 32 ko (32 768 caractères). L’inclusion de FetchXML comme paramètre dans l’URL peut atteindre la limite. Vous pouvez exécuter une $batch
opération en utilisant une POST
requête comme moyen de déplacer le FetchXML hors de l’URL et dans le corps de la requête là où la limite n’existe pas. ne s’applique pas. L’envoi d’une requête GET
dans $batch
autorise les URL d’une longueur maximale de 64 Ko (65 536 caractères). Bien plus qu’avec une demande GET
normale, mais ce n’est pas illimité. Pour plus d’informations : Exécuter des opérations par lots à l’aide de l’API Web.
Exemple
Demande :
POST [Organization URI]/api/data/v9.2/$batch HTTP/1.1
Content-Type:multipart/mixed;boundary=batch_AAA123
Accept:application/json
OData-MaxVersion:4.0
OData-Version:4.0
--batch_AAA123
Content-Type: application/http
Content-Transfer-Encoding: binary
GET [Organization URI]/api/data/v9.2/accounts?fetchXml=%3Cfetch%20mapping='logical'%3E%3Centity%20name='account'%3E%3Cattribute%20name='accountid'/%3E%3Cattribute%20name='name'/%3E%3Cattribute%20name='telephone1'/%3E%3Cattribute%20name='accountid'/%3E%3Cattribute%20name='creditonhold'/%3E%3C/entity%3E%3C/fetch%3E HTTP/1.1
Content-Type: application/json
OData-Version: 4.0
OData-MaxVersion: 4.0
--batch_AAA123--
Réponse :
--batchresponse_cbfd44cd-a322-484e-913b-49e18af44e34
Content-Type: application/http
Content-Transfer-Encoding: binary
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"@odata.context":"[Organization URI]/api/data/v9.2/$metadata#accounts(accountid,name,telephone1,creditonhold)",
"value":[
{
"@odata.etag":"W/\"563737\"",
"accountid":"1f55c679-485e-e811-8151-000d3aa3c22a",
"name":"Fourth Coffee (sample)",
"telephone1":"+1-425-555-0121",
"creditonhold":false
},
{
"@odata.etag":"W/\"563739\"",
"accountid":"2555c679-485e-e811-8151-000d3aa3c22a",
"name":"Litware, Inc. (sample)",
"telephone1":"+1-425-555-0120",
"creditonhold":false
}
]
}
--batchresponse_cbfd44cd-a322-484e-913b-49e18af44e34--
Voir aussi
Utiliser FetchXML pour construire une requête
Interroger les données à l’aide de l’API web
Extraire et exécuter des requêtes prédéfinies
Notes
Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)
Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).