Web API では、ページング Cookie を注釈としてリクエストする必要があります。 これらのリクエスト ヘッダーを使用すると、次のようになります:
Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
OR for all annotations:
Prefer: odata.include-annotations="*"
これらの注釈は結果とともに返されます:
@Microsoft.Dynamics.CRM.fetchxmlpagingcookie
@Microsoft.Dynamics.CRM.morerecords
次の一連の FetchXML 要求は、ページング クッキーの使用を示しています。 この例では、小さな count
簡潔にするために値 (3) を使用します。
<fetch count='3' page='1'>
<entity name='contact'>
<attribute name='fullname' />
<attribute name='jobtitle' />
<attribute name='annualincome' />
<order descending='true' attribute='fullname' />
</entity>
</fetch>
最初のページ
page
を '1'
に設定して最初のページを送信します。
このリクエスト ヘッダーを使用します:
Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
応答内のページング Cookie とその他のレコードの注釈が確実に返されるようにします。
要求:
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch%20count%3D%273%27%20page%3D%271%27%3E%0D%0A%3Centity%20name%3D%27contact%27%3E%0D%0A%3Cattribute%20name%3D%27fullname%27%2F%3E%0D%0A%3Cattribute%20name%3D%27jobtitle%27%2F%3E%0D%0A%3Cattribute%20name%3D%27annualincome%27%2F%3E%0D%0A%3Corder%20descending%3D%27true%27%20attribute%3D%27fullname%27%2F%3E%0D%0A%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E&$count=true
Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
応答:
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,annualincome,_transactioncurrencyid_value,transactioncurrencyid,contactid,transactioncurrencyid())",
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": "<cookie pagenumber=\"2\" pagingcookie=\"%253ccookie%2520page%253d%25221%2522%253e%253cfullname%2520last%253d%2522Susanna%2520Stubberod%2520%2528sample%2529%2522%2520first%253d%2522Yvonne%2520McKay%2520%2528sample%2529%2522%2520%252f%253e%253ccontactid%2520last%253d%2522%257b70BF4D48-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b49B0BE2E-D01C-ED11-B83E-000D3A572421%257d%2522%2520%252f%253e%253c%252fcookie%253e\" istracking=\"False\" />",
"@Microsoft.Dynamics.CRM.morerecords": true,
"value": [
{
"@odata.etag": "W/\"72201545\"",
"fullname": "Yvonne McKay (sample)",
"jobtitle": "Coffee Master",
"annualincome": 45000.0000,
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "49b0be2e-d01c-ed11-b83e-000d3a572421"
},
{
"@odata.etag": "W/\"80648856\"",
"fullname": "Thomas Andersen (sample)",
"jobtitle": "Purchasing Manager",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "86bf4d48-34cb-ed11-b596-0022481d68cd"
},
{
"@odata.etag": "W/\"80648695\"",
"fullname": "Susanna Stubberod (sample)",
"jobtitle": "Purchasing Manager",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd"
}
]
}
応答では、@Microsoft.Dynamics.CRM.morerecords
注釈の値は、条件に一致するレコードがさらに存在することを示します。
@Microsoft.Dynamics.CRM.fetchxmlpagingcookie
注釈値は、返されたレコードに関するページング情報を提供します。 @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
値は XML 要素です。 次のリクエストでの要素の pagingcookie
属性値を使う必要があります。
pagingcookie
属性値は、2 回 URL エンコードされます。 これを確認する必要はありませんが、この例のデコードされフォーマットされた値は次のようになります:
<cookie page="1">
<fullname last="Susanna Stubberod (sample)"
first="Yvonne McKay (sample)" />
<contactid last="{70BF4D48-34CB-ED11-B596-0022481D68CD}"
first="{49B0BE2E-D01C-ED11-B83E-000D3A572421}" />
</cookie>
次のページ
前のページ @Microsoft.Dynamics.CRM.morerecords
の注釈値が true
である場合、それ以降のすべてのリクエストで、以下のことが必要です:
fetch
エレメントの page
属性値をインクリメントする必要があります。
pagingcookie
属性値を 2 回 URL デコードする必要があります。
デコードされた pagingcookie
属性値を XML エンコードし、それを fetch
エレメントの paging-cookie
属性の値として設定する必要があります。
注意
値を明示的に XML エンコードする必要があるかどうかは、使用するテクノロジによって異なります。 .NET では、XML 値を別の XML 要素の属性に設定する際、自動的に実行される場合があります。
最初の要求で行ったように、FetchXml 値全体を URL エンコードします。
次のリクエストでは、URL エンコードされる前の FetchXML は次のようになります。
<fetch count='3' page='2' paging-cookie='<cookie page="1"><fullname last="Susanna Stubberod (sample)" first="Yvonne McKay (sample)" /><contactid last="{70BF4D48-34CB-ED11-B596-0022481D68CD}" first="{49B0BE2E-D01C-ED11-B83E-000D3A572421}" /></cookie>'>
<entity name='contact'>
<attribute name='fullname' />
<attribute name='jobtitle' />
<attribute name='annualincome' />
<order descending='true' attribute='fullname' />
</entity>
</fetch>
要求:
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch%20count%3D%273%27%20page%3D%272%27%20paging-cookie%3D%27%26lt%3Bcookie%20page%3D%221%22%26gt%3B%26lt%3Bfullname%20last%3D%22Susanna%20Stubberod%20%28sample%29%22%20first%3D%22Yvonne%20McKay%20%28sample%29%22%20%2F%26gt%3B%26lt%3Bcontactid%20last%3D%22%7B70BF4D48-34CB-ED11-B596-0022481D68CD%7D%22%20first%3D%22%7B49B0BE2E-D01C-ED11-B83E-000D3A572421%7D%22%20%2F%26gt%3B%26lt%3B%2Fcookie%26gt%3B%27%3E%0D%0A%3Centity%20name%3D%27contact%27%3E%0D%0A%3Cattribute%20name%3D%27fullname%27%2F%3E%0D%0A%3Cattribute%20name%3D%27jobtitle%27%2F%3E%0D%0A%3Cattribute%20name%3D%27annualincome%27%2F%3E%0D%0A%3Corder%20descending%3D%27true%27%20attribute%3D%27fullname%27%2F%3E%0D%0A%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E
Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
応答:
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,_transactioncurrencyid_value,transactioncurrencyid,contactid,annualincome,transactioncurrencyid())",
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": "<cookie pagenumber=\"2\" pagingcookie=\"%253ccookie%2520page%253d%25222%2522%253e%253cfullname%2520last%253d%2522Scott%2520Konersmann%2520%2528sample%2529%2522%2520first%253d%2522Susan%2520Burk%2520%2528sample%2529%2522%2520%252f%253e%253ccontactid%2520last%253d%2522%257b78BF4D48-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b84BF4D48-34CB-ED11-B596-0022481D68CD%257d%2522%2520%252f%253e%253c%252fcookie%253e\" istracking=\"False\" />",
"@Microsoft.Dynamics.CRM.morerecords": true,
"value": [
{
"@odata.etag": "W/\"80648842\"",
"fullname": "Susan Burk (sample)",
"jobtitle": "Owner",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "84bf4d48-34cb-ed11-b596-0022481d68cd"
},
{
"@odata.etag": "W/\"80648744\"",
"fullname": "Sidney Higa (sample)",
"jobtitle": "Owner",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "76bf4d48-34cb-ed11-b596-0022481d68cd"
},
{
"@odata.etag": "W/\"80648758\"",
"fullname": "Scott Konersmann (sample)",
"jobtitle": "Purchasing Manager",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "78bf4d48-34cb-ed11-b596-0022481d68cd"
}
]
}
最後のページ
最後のページでは、@Microsoft.Dynamics.CRM.morerecords
と @Microsoft.Dynamics.CRM.fetchxmlpagingcookie
注釈は応答に含まれません。
要求:
GET [Organization Uri]/api/data/v9.2/contacts?fetchXml=%3Cfetch%20count%3D%273%27%20page%3D%275%27%20paging-cookie%3D%27%26lt%3Bcookie%20page%3D%224%22%26gt%3B%26lt%3Bfullname%20last%3D%22Maria%20Campbell%20%28sample%29%22%20first%3D%22Patrick%20Sands%20%28sample%29%22%20%2F%26gt%3B%26lt%3Bcontactid%20last%3D%22%7B74BF4D48-34CB-ED11-B596-0022481D68CD%7D%22%20first%3D%22%7B82BF4D48-34CB-ED11-B596-0022481D68CD%7D%22%20%2F%26gt%3B%26lt%3B%2Fcookie%26gt%3B%27%3E%0D%0A%3Centity%20name%3D%27contact%27%3E%0D%0A%3Cattribute%20name%3D%27fullname%27%2F%3E%0D%0A%3Cattribute%20name%3D%27jobtitle%27%2F%3E%0D%0A%3Cattribute%20name%3D%27annualincome%27%2F%3E%0D%0A%3Corder%20descending%3D%27true%27%20attribute%3D%27fullname%27%2F%3E%0D%0A%3C%2Fentity%3E%0D%0A%3C%2Ffetch%3E
Prefer: odata.include-annotations="Microsoft.Dynamics.CRM.fetchxmlpagingcookie,Microsoft.Dynamics.CRM.morerecords"
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
応答:
HTTP/1.1 200 OK
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#contacts(fullname,jobtitle,_transactioncurrencyid_value,transactioncurrencyid,contactid,annualincome,transactioncurrencyid())",
"value": [
{
"@odata.etag": "W/\"87523026\"",
"fullname": "Jim Glynn (sample)",
"jobtitle": "Owner",
"_transactioncurrencyid_value": "228f42f8-e646-e111-8eb7-78e7d162ced1",
"contactid": "80bf4d48-34cb-ed11-b596-0022481d68cd"
}
]
}
Web API ページングの例
HttpClient で C# を使用する場合、次の RetrieveAll
静的メソッドは FetchXml クエリに一致するすべてのレコードを返し、レコード数がページサイズを超える場合は複数のリクエストを送信します。
/// <summary>
/// Returns all records matching the criteria
/// </summary>
/// <param name="client">The authenticated HttpClient instance.</param>
/// <param name="entitySetName">The EntitySetName for the table used in the fetchXml</param>
/// <param name="fetchXml">The FetchXml query string</param>
/// <param name="pageSize">The page size to use. Default is 5000</param>
/// <returns>All the records that match the criteria</returns>
/// <exception cref="Exception"></exception>
static async Task<List<JsonObject>> RetrieveAll(HttpClient client,
string entitySetName,
string fetchXml,
int pageSize = 5000)
{
List<JsonObject> entities = new();
XElement fetchNode = XElement.Parse(fetchXml);
int page = 1; //Start with page 1
// Set the fetch page attribute
fetchNode.SetAttributeValue("page", page);
// Set the fetch count attribute
fetchNode.SetAttributeValue("count", pageSize);
while (true)
{
bool moreRecords;
string pagingCookie = null;
// Prepare the request
HttpRequestMessage request = new()
{
Method = HttpMethod.Get,
RequestUri = new Uri(
uriString: $"{entitySetName}?fetchXml={HttpUtility.UrlEncode(fetchNode.ToString())}",
uriKind: UriKind.Relative),
};
// Add annotations to return formatted values
request.Headers.Add("Prefer", "odata.include-annotations=" +
"\"Microsoft.Dynamics.CRM.fetchxmlpagingcookie," +
"Microsoft.Dynamics.CRM.morerecords\"");
// Send the request
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
string jsonContent = await response.Content.ReadAsStringAsync();
// Using System.Text.Json.Nodes
JsonObject content = JsonNode.Parse(jsonContent)?.AsObject();
// Records are in the 'value' property
content.TryGetPropertyValue("value", out JsonNode records);
// Add records to the list
entities.AddRange(records.AsArray().Cast<JsonObject>());
// Detect if there are more records
moreRecords = content.
TryGetPropertyValue("@Microsoft.Dynamics.CRM.morerecords", out _);
if (moreRecords)
{
// Get the paging cookie value
if (content.
TryGetPropertyValue("@Microsoft.Dynamics.CRM.fetchxmlpagingcookie",
out JsonNode fetchxmlpagingcookie))
{
pagingCookie = fetchxmlpagingcookie.AsValue().ToString();
}
}
}
else
{
throw new Exception($"Web API call failed. Status Code: {response.StatusCode}");
}
if (!moreRecords)
{
// Stop sending requests
break;
}
XElement cookieElement = XElement.Parse(pagingCookie);
// Extract the pagingcookie attribute
XAttribute pagingcookieAttribute = cookieElement.Attribute("pagingcookie");
// Decode the pagingcookie attribute twice
pagingCookie = HttpUtility.UrlDecode(HttpUtility.UrlDecode(pagingcookieAttribute.Value));
// Set the fetch paging-cookie attribute with the paging cookie from the previous query
fetchNode.SetAttributeValue("paging-cookie", pagingCookie);
// Increment the fetch page attribute value
fetchNode.SetAttributeValue("page", page++);
}
// Return the records from all requests
return entities;
}
次の手順で、クイック スタート: Web API サンプル (C#) の実行 サンプルを調整して、FetchXml クエリをテストできます。
Program
クラスに RetrieveAll
静的メソッドを追加します。
- 以下に示すように、
Main
メソッドを変更し、Web API call
領域のコンテンツを置き換えます。
# <a name="region-web-api-call"></a>region Web API call
string fetchXml = @"<fetch count='3' page='1'>
<entity name='contact'>
<attribute name='fullname'/>
<attribute name='jobtitle'/>
<attribute name='annualincome'/>
<order descending='true' attribute='fullname'/>
</entity>
</fetch>";
List<JsonObject> records = await RetrieveAll(client: client,
entitySetName: "contacts",
fetchXml: fetchXml,
pageSize: 3);
Console.WriteLine($"Success: {records.Count}");
# <a name="endregion-web-api-call"></a>endregion Web API call
重要
このクエリは、条件に一致するすべてのレコードを返します。 結果を制限するには、フィルター要素を必ず含めてください。
entitySetName
パラメータは、FetchXml エンティティ要素 で指定されているのと同じテーブルの エンティティ セット名 name
である必要があります。属性。