Search code examples
dynamics-crmdynamics-365fetchxml

Invalid XML. ---&gt On A Plugin Containing FetchXML


This happens when there is &, or other invalid characters in the contract name. My question is, how do I deal with these invalid characters??!!

Microsoft.Crm.CrmException: Invalid XML. ---> System.Xml.XmlException: An error occurred while parsing EntityName. Line 13, position 117. at System.Xml.XmlTextReaderImpl.Throw(Exception e) at System.Xml.XmlTextReaderImpl.HandleEntityReference(Boolean isInAttributeValue, EntityExpandType expandType, Int32& charRefEndPos) at System.Xml.XmlTextReaderImpl.ParseAttributeValueSlow(Int32 curPos, Char quoteChar, NodeData attr) at System.Xml.XmlTextReaderImpl.ParseAttributes() at System.Xml.XmlTextReaderImpl.ParseElement() at System.Xml.XmlTextReaderImpl.ParseElementContent() at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r) at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o) at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options) at Microsoft.Crm.Platform.Server.Utility.XmlHelper.LoadXmlInfo(String xmlInfo) at Microsoft.Crm.Query.EntityExpression.ExtractPlatformName(String fetchXml, XElement element).

Here is the code in questions:

//run a fetchXml query to get how many contract lines have these values

string fetchLines = @"
  <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
    <entity name='new_yummycontractline'>
      <attribute name='new_yummycontractlineid' />
      <filter type='and'>
        <condition attribute='new_servingtime' operator='eq' value='" + servingTime.ToString() + @"' />
        <condition attribute='new_servinggroup' operator='eq' value='" + servingGroup.ToString() + @"' />
        <condition attribute='new_destination' operator='eq' value='" + location.ToString() + @"' />
        <condition attribute='statecode' operator='eq' value='0' />
      </filter>
      <link-entity name='new_yummycontract' from='new_yummycontractid' to='new_contractid' link-type='inner' alias='ad'>
        <filter type='and'>
          <condition attribute='new_yummycontractid' operator='eq' uiname='" + uiname + @"' uitype='new_yummycontract' value='" + contractId.ToString() + @"' />
        </filter>
      </link-entity>
    </entity>
  </fetch>";

EntityCollection results = service.RetrieveMultiple(new FetchExpression(fetchLines));

Solution

  • uiname and uitype are not required for your fetchXml to work. These are used for presentation and not for the query. I think these are added by the Advanced Find editor; hence the "UI"

    You can rewrite that section of XML like so

    <link-entity name='new_yummycontract' from='new_yummycontractid' to='new_contractid' link-type='inner' alias='ad'>
      <filter type='and'>
        <condition attribute='new_yummycontractid' operator='eq' value='" + contractId.ToString() + @"' />
      </filter>
    </link-entity>
    

    Not sure which version of .NET you're using, but you can also use the $ special character to indicate an interpolated string which I think increases readability and reduces string concatenation

    string fetchLines = @$"
      <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
        <entity name='new_yummycontractline'>
          <attribute name='new_yummycontractlineid' />
          <filter type='and'>
            <condition attribute='new_servingtime' operator='eq' value='{servingTime}' />
            <condition attribute='new_servinggroup' operator='eq' value='{servingGroup}' />
            <condition attribute='new_destination' operator='eq' value='{location}' />
            <condition attribute='statecode' operator='eq' value='0' />
          </filter>
          <link-entity name='new_yummycontract' from='new_yummycontractid' to='new_contractid' link-type='inner' alias='ad'>
            <filter type='and'>
              <condition attribute='new_yummycontractid' operator='eq' value='{contractId}' />
            </filter>
          </link-entity>
        </entity>
      </fetch>";