Request URL Too Long for fetchXml query types - asp.net-web-api

I'm using CRM 2016 web api with fetchxml query parameter, but my query is too long it's simulate the IN operator were the number of parameters passed in the IN list are 300 elements and some times will be more than that.
So my problem is the query are too big for a GET HTTP Request. I have tried to send the query in the http message body but that didn't work so what is the solution for this problem?
Here's a code snippet of the fetchxml query that I used:
<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
The CRM web api endpoint that I request is :
GET http://<org>/api/data/v8.0/<entity>?fetchXml=<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
This is the response I got from the api.
Error code: 414: HTTP/1.1 414 Request-URI Too Long Response : "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\"\"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">\r\n<HTML><HEAD><TITLE>Request URL Too Long<\/TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text\/html; charset=us-ascii\"><\/HEAD>\r\n<BODY><h2>Request URL Too Long<\/h2>\r\n<hr><p>HTTP Error 414. The request URL is too long.<\/p>\r\n<\/BODY><\/HTML>\r\n" [] []

You'll need to use a Post, not a Get:
https://dreamingincrm.com/2017/01/15/executing-large-fetchxml-with-webapi/

Using the "in" operator with a big list of ids is probably not the best way to query, as you've seen. It would be better if you could filter on an attribute of the new_classopportunity entity by using a link-entity, like this:
<fetch mapping="logical" distinct="true" >
<entity name="entity" >
<!-- ... all your attributes ... -->
<link-entity name="new_classopportunity" from="new_classopportunityid" to="new_classopportunityid" >
<attribute name="new_name" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Notice you can pull in attributes from the link-entity as well. In this case I'm pulling in name and using a filter to only get new_classopportunity records that are active.
If you don't have a field on new_classopportunity that you can filter on to get the same list, add one! :)

Related

Filter users by type Dynamics 365

I am trying to exclude App Users from a view in Dynamics 365 CRM. The fetch xml is very simple:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="systemuser">
<attribute name="fullname" />
<attribute name="businessunitid" />
<attribute name="title" />
<attribute name="address1_telephone1" />
<attribute name="positionid" />
<attribute name="systemuserid" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="type" operator="ne" value="App User" />
</filter>
</entity>
</fetch>
I need to place a filter in my query like this seudo code: <condition attribute="type" operator="ne" value="App User" />, sort of a field that allows me to filter by user type. Is there any field that could deterministically say that a user is an app user?
Typically, Non-interactive App user will be created with the attribute Access mode = 4 in system user entity. So this should work.
<condition attribute="accessmode" operator="ne" value="4" />

FetchXML or condition on the attributes of two related entities

The requirements for this FetchXML statement are:
Return all 'ebs_opportunityinternshipunit' where
'createdon' is 'last-week'
and
'owner' of 'account' is 'eq-userid'
'account' is referenced by 'parentaccountid' of 'opportunity'
or
'owner' of 'account2' is 'eq-userid'
'account2' is referenced by 'mitacs_partner2' of 'opportunity'
I've tried configuring the filter with out-of-the-box tools, XRMToolbox FetchXML Builder, visiting the official CRM Community forum, and reading FetchXML documentation. Still, the best that I've been able to come up with is below:
<fetch version="1.0" mapping="logical">
<entity name="ebs_opportunityinternshipunit">
<attribute name="ebs_name" />
<attribute name="createdon" />
<attribute name="ebs_opportunityinternshipunitid" />
<order attribute="ebs_name" descending="false" />
<filter type="and">
<condition attribute="createdon" operator="last-week" />
<filter type="or">
<condition entityname="ab" attribute="ownerid" operator="eq-userid" />
<condition entityname="ac" attribute="ownerid" operator="eq-userid" />
</filter>
</filter>
<link-entity name="opportunity" from="opportunityid" to="ebs_opportunity" link-type="inner" alias="aa">
<link-entity name="account" from="accountid" to="parentaccountid" link-type="inner" alias="ab" />
<link-entity name="account" from="accountid" to="mitacs_partner2" link-type="inner" alias="ac" />
</link-entity>
</entity>
</fetch>

How to pass null or empty to FetchXML filters?

Scenario: I've a text field in Dynamics CRM on Order Type. This field is integrated with some other systems and it'll be accepting only already stated list of values; like, ABC, IJK, XYZ etc. Now I can query this field using Advanced find if it contain data or not.
Now in report, I've a parameter that is having all those possible value and one additional as "Does not contain data" and its value is empty string. I've also enabled this report parameter for multi-select. But I am unable to get the orders if any of the value is selected from report parameters.
Below is my FetchXML query, Please let me know what I am missing in below.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Unfortunately you cannot combine the values ("ABC", "IJK", "XYZ") with an empty string option. Think about how SSRS will parse the empty string into FetchXml:
<condition attribute="tv_ordertype" operator="in" value="" />
Because the in operator has an empty string, there will be no matching results.
One approach that might work is to change your FetchXml to use an or filter, like this
<filter type="or">
<condition attribute="tv_ordertype" operator="null" />
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
This will now return all values from CRM that match your criteria OR have a null tv_ordertype
Then you can apply additional filtering at the tablix / report level
Try something like below
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type='and'>
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Your fetch XML should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in"/>
<value>#Order_Types[0]</value>
<value>#Order_Types[1]</value>
<!-- etc -->
</condition>
</filter>
</entity>
</fetch>

How to filter using fetch to get accurate results?

I need to get all accounts that have phonecalls in state not open, so I created a query on fetch and got some results.
After checking my results I found that I got all accounts that have minimum 1 phonecall that was not open, but I need to get the accounts that all of their connected phonecalls are not open (can't have even 1 in open state) is it possible to do by fetch ?
** by NOT OPEN I mean state of Canceled or Completed.
Here is my fetch query:
#"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='account'>
<attribute name='name' />
<order attribute='accountamount' descending='true' />
<link-entity name='phonecall' from='regardingobjectid' to='accountid' alias='ab'>
<filter type='and'>
<condition attribute='statecode' operator='ne' value='0' />
</filter>
</link-entity>
</entity>
</fetch>";
What you are looking for is Unmatch query. This can be achieved in 2 queries using fetchxml.
First Query: You have to pull all the Accounts with open phonecalls.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="account" >
<attribute name="accountid" />
<order attribute="accountamount" descending="true" />
<link-entity name="phonecall" from="regardingobjectid" to="accountid" alias="ab" >
<filter type="and" >
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Second Query: Iterate & pass the first query Account resultset as <value> like below, to filter out them.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="account" >
<attribute name="name" />
<attribute name="primarycontactid" />
<attribute name="telephone1" />
<attribute name="accountid" />
<order attribute="name" descending="false" />
<filter type="and" >
<condition attribute="accountid" operator="not-in" >
<value><GUID of ACCOUNT1 with OPEN PHONECALL></value>
<value><GUID of ACCOUNT2 with OPEN PHONECALL></value>
<value><GUID of ACCOUNT3 with OPEN PHONECALL></value>
</condition>
</filter>
</entity>
</fetch>
Read for idea

Dynamics - How to get all appointments that for a specific user attends by Web Api

In Dynamics CRM, I'm trying to get all the appointments where a specific user is an attendee, using Web API. I know that I have to deal with Appointment entity and ActivityParty with activitypartytypemask equals 9 but really cannot figure out how to make it. How can identify the attendee ?
You can use FetchXml for your purpose. Check following Fetch:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="appointment">
<attribute name="subject" />
<attribute name="statecode" />
<attribute name="scheduledstart" />
<attribute name="scheduledend" />
<attribute name="regardingobjectid" />
<attribute name="activityid" />
<link-entity name="activityparty" from="activityid" to="activityid" alias="aa">
<filter type="and">
<condition attribute="participationtypemask" operator="in">
<value>6</value>
<value>5</value>
</condition>
<condition attribute="partyid" operator="eq" value="{9CE2BF21-408B-E611-80F3-C4346BAC7ABC}" />
</filter>
</link-entity>
</entity>
</fetch>
Using provided FetchXml and WebApi you should get the result you wanted. Url should look like following:
[Server Base Url]/api/data/v8.2/appointments?fetchXml=%3Cfetch%20version%3D%221.0%22%20output-format%3D%22xml-platform%22%20mapping%3D%22logical%22%20distinct%3D%22true%22%3E%3Centity%20name%3D%22appointment%22%3E%3Cattribute%20name%3D%22subject%22%20%2F%3E%3Cattribute%20name%3D%22statecode%22%20%2F%3E%3Cattribute%20name%3D%22scheduledstart%22%20%2F%3E%3Cattribute%20name%3D%22scheduledend%22%20%2F%3E%3Cattribute%20name%3D%22regardingobjectid%22%20%2F%3E%3Cattribute%20name%3D%22activityid%22%20%2F%3E%3Clink-entity%20name%3D%22activityparty%22%20from%3D%22activityid%22%20to%3D%22activityid%22%20alias%3D%22aa%22%3E%3Cfilter%20type%3D%22and%22%3E%3Ccondition%20attribute%3D%22participationtypemask%22%20operator%3D%22in%22%3E%3Cvalue%3E6%3C%2Fvalue%3E%3Cvalue%3E5%3C%2Fvalue%3E%3C%2Fcondition%3E%3Ccondition%20attribute%3D%22partyid%22%20operator%3D%22eq%22%20value%3D%22%7B9CE2BF21-408B-E611-80F3-C4346BAC7ABC%7D%22%20%2F%3E%3C%2Ffilter%3E%3C%2Flink-entity%3E%3C%2Fentity%3E%3C%2Ffetch%3E
This article contains additional details.

Resources