You can easily execute fetchxml in WebAPI using the “fetchXml” query parameter. But this “GET” method won’t work, if the fetchxml is too big. In this case, you have to use the “POST” method to execute the fetchxml.
Sample Request Header:
Accept: application/json OData-MaxVersion: 4.0 OData-Version: 4.0 Content-Type: multipart/mixed;boundary=batch_contactfetch
Sample Request Body:
--batch_contactfetch Content-Type: application/http Content-Transfer-Encoding: binary GET https://[CRM URL]/api/data/v8.2/contacts?fetchXml=<fetch count="10" ><entity name="contact" ><attribute name="fullname" /></entity></fetch> HTTP/1.1 Content-Type: application/json OData-Version: 4.0 OData-MaxVersion: 4.0 --batch_contactfetch--
Sample Code:
var req = new XMLHttpRequest(); req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/$batch", true); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "multipart/mixed;boundary=batch_contactfetch"); req.onreadystatechange = function() { if (this.readyState === 4) { req.onreadystatechange = null; if (this.status === 200) { var response = JSON.parse(this.response.substring(this.response.indexOf('{'),this.response.lastIndexOf('}')+1)); console.log(response.value); } else { Xrm.Utility.alertDialog(this.statusText); } } }; var body = '--batch_contactfetch\n' body += 'Content-Type: application/http\n' body += 'Content-Transfer-Encoding: binary\n' body += '\n' body += 'GET ' + Xrm.Page.context.getClientUrl()+'/api/data/v8.2/contacts?fetchXml=<fetch count="10" ><entity name="contact" ><attribute name="fullname" /></entity></fetch> HTTP/1.1\n' body += 'Content-Type: application/json\n' body += 'OData-Version: 4.0\n' body += 'OData-MaxVersion: 4.0\n' body += '\n' body += '--batch_contactfetch--' req.send(body);
Request Screenshot
Response Screenshot
Thank you I will try to implement this from php
Thank you man it’s working
That’s great 👍
I still have an issue with a “Huge” fetchxml (+ 70000 length) -> “Invalid URI: The Uri string is too long”.
The fetchxml contains a lot of checks on postalcodes, that’s why it’s so big. It worked in “CRM 2011” with “SOAP”.
Is there a way we can make it work with huge FetchXML?
That is the limitation this post addresses. You send the GET request of the url with the fetchxml query parameter in the body of the batch request. Is the code provided in the post not working for you?
Hi,
Thanks for your post we are able to execute the fetchxml using batch request but when we tried to retrieve more than 5k records then we got below error.
We have added page number and paging-cookie in fetchxml to retrieve more records. Can anyone faced such kind of issue and solution for it.
{“error”:{“code”:”0x80040216″,”message”:”An unexpected error occurred.”,”innererror”:{“message”:”An unexpected error occurred.”,”type”:”System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]”,”stacktrace”:” at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.RetrieveMultiple(QueryBase query, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode, Guid appModuleId)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataExecutionContext.RetrieveMultiple(QueryBase query)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.ExecuteQueryForEntitySet(CrmODataExecutionContext context, String entitySetName, CustomQueryOptions queryOptions, String fetchXml)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.RetrieveEdmEntityCollection(CrmODataExecutionContext context, String entityCollectionName, String castedEntityName, ODataQueryOptions queryOptions)\r\n at Microsoft.Crm.Extensibility.OData.EntityController.GetEntitySet(String entitySetName)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.c__DisplayClass10.b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n— End of stack trace from previous location where exception was thrown —\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()\r\n— End of stack trace from previous location where exception was thrown —\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n— End of stack trace from previous location where exception was thrown —\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()”}}}
–batchresponse_aab8bc56-001e-4bb1-b6b2-f8ef3db7d01f–
Can you try using Xrm WebApi Client library -> https://github.com/DigitalFlow/Xrm-WebApi-Client#retrieve-by-fetchxml and see if you still get the same exception?
Hi this is working great, but I’m trying to retrieve the annotations by adding the header “odata.include-annotations=OData.Community.Display.V1.FormattedValue”
I can see the header in the multipart request, but it doesn’t seem to be honored. Any ideas?
This worked for me in 8.2 without any issue. I tried with both odata.include-annotations=”*” as well as odata.include-annotations=”OData.Community.Display.V1.FormattedValue”. Try generating the code through CRM Rest Builder (https://github.com/jlattimer/CRMRESTBuilder) and see whether you get the same behaviour.