Partage via


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.

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 :

  1. Incrémenter la valeur d’attribut page de l’élément fetch.

  2. décoder l’URL de la valeur d’attribut pagingcookie deux fois.

  3. encoder en XML la valeur d’attribut pagingcookie décodée et la définir comme la valeur d’un attribut paging-cookie sur l’élément fetch.

    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.

  4. 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="&lt;cookie page=&quot;1&quot;&gt;&lt;fullname last=&quot;Robert Lyon (sample)&quot; first=&quot;Susanna Stubberod (sample)&quot; /&gt;&lt;contactid last=&quot;{30717E9C-643F-ED11-9DB0-002248225E95}&quot; first=&quot;{20717E9C-643F-ED11-9DB0-002248225E95}&quot; /&gt;&lt;/cookie&gt;">
  <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é).