You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET通过WebAPI用FetchXml查询Dataverse含#字符序列号问题

问题

在.NET中通过WebAPI使用FetchXml从Dynamics 365 CE(Dataverse)检索记录,因限制只能用GET请求,需在查询字符串中过滤含#等特殊字符的SerialNumber字段,但直接传入会导致XML无效。尝试过WebUtility.UrlEncode、HtmlEncode及双重编码,均无法正确检索到对应记录。当前使用的FetchXml模板如下:

<fetch>
    <entity name='{im_customerequipment.EntityLogicalName}'>
        <attribute name='{im_customerequipment.Fields.Id}' />
        <attribute name='{im_customerequipment.Fields.im_SerialNo}' />
        <attribute name='{im_customerequipment.Fields.im_AccountId}' />
        <filter>
            <condition attribute='{im_customerequipment.Fields.OwningBusinessUnit}' operator='eq' value='{businessUnitId.ToString()}'/>
            <condition attribute='{im_customerequipment.Fields.im_SerialNo}' operator='in'>
                {string.Join("", serialNumbers.Skip(page * pageSize).Take(pageSize).Select(serialNumber => $"<value>{serialNumber}</value>"))}
            </condition>
    </filter>
</entity>

请问如何正确转义#字符,使其在Dataverse端能被正确识别并检索到对应记录?

解决方案

针对Dataverse GET请求中FetchXml含特殊字符的转义,需遵循先XML转义,再URL编码的顺序,具体步骤如下:

  • 对单个序列号做XML实体转义
    对于#这类特殊字符,首先要转义为XML实体&#35;,同时处理其他可能破坏XML结构的字符(如<、>、&、'、")。推荐使用System.Security.SecurityElement.Escape()方法,它会自动将所有XML特殊字符转换为对应实体。

  • 生成完整FetchXml后再做URL编码
    先将转义后的序列号插入FetchXml模板生成完整XML字符串,再对整个XML做URL编码,最后拼接到GET请求的fetchXml查询参数中。

代码示例

修改生成<value>节点的逻辑,加入XML转义步骤:

// 对每个序列号先执行XML转义
var escapedSerialNumbers = serialNumbers
    .Skip(page * pageSize)
    .Take(pageSize)
    .Select(sn => System.Security.SecurityElement.Escape(sn));

// 生成FetchXml中的<value>节点片段
var valueNodes = string.Join("", escapedSerialNumbers.Select(sn => $"<value>{sn}</value>"));

// 拼接完整的FetchXml字符串
string fetchXml = $@"<fetch>
    <entity name='{im_customerequipment.EntityLogicalName}'>
        <attribute name='{im_customerequipment.Fields.Id}' />
        <attribute name='{im_customerequipment.Fields.im_SerialNo}' />
        <attribute name='{im_customerequipment.Fields.im_AccountId}' />
        <filter>
            <condition attribute='{im_customerequipment.Fields.OwningBusinessUnit}' operator='eq' value='{businessUnitId.ToString()}'/>
            <condition attribute='{im_customerequipment.Fields.im_SerialNo}' operator='in'>
                {valueNodes}
            </condition>
        </filter>
    </entity>
</fetch>";

// 对整个FetchXml执行URL编码
string encodedFetchXml = WebUtility.UrlEncode(fetchXml);

// 拼接最终的GET请求URL
string requestUrl = $"https://your-org.crm.dynamics.com/api/data/v9.2/{im_customerequipment.EntityLogicalName}?fetchXml={encodedFetchXml}";

关键说明

  • 禁止直接对原始序列号做URL编码后插入XML,这会导致XML解析错误(URL编码后的#是%23,XML会将其视为普通文本,而Dataverse需要的是原始字符的XML实体表示)。
  • SecurityElement.Escape()会处理所有XML预定义实体,包括:
    • & → &amp;
    • < → &lt;
    • > → &gt;
    • ' → &apos;
    • " → &quot;
    • # → &#35;
  • 最后对整个FetchXml做URL编码,确保字符串能安全通过查询字符串传输,不会被浏览器或服务器截断。

内容的提问来源于stack exchange,提问作者Flashcap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:44:59