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

跨服务器获取Dynamics CRM账户字段遇DisplayName空值异常

解决Dynamics 365 RetrieveEntityRequest获取字段DisplayName为空的问题

根据你描述的场景,这个问题大概率和元数据发布状态、本地化标签的获取逻辑以及RetrieveAsIfPublished参数的设置有关。下面是几个针对性的解决方案,你可以逐一尝试:

1. 修改RetrieveAsIfPublished参数为true

你当前请求里设置了RetrieveAsIfPublished = false,这会获取系统中已发布的元数据,但如果自定义字段刚添加到表单且发布过程存在延迟/异常,可能导致元数据不同步。改成true后,会获取最新的(包括未完全发布的)元数据,能避免这类同步问题:

RetrieveEntityRequest request = new RetrieveEntityRequest() { 
    EntityFilters = EntityFilters.Attributes, 
    RetrieveAsIfPublished = true, // 这里改为true
    LogicalName = "account" 
};

2. 替换UserLocalizedLabel为指定语言的标签获取逻辑

UserLocalizedLabel依赖当前用户的语言设置,如果组织默认语言和用户语言不匹配,或者自定义字段未在该语言下配置标签,就会返回null。建议直接获取组织默认语言的标签(比如中文用2052,英文用1033),或者遍历所有标签取第一个非空值作为兜底:

// 示例:获取组织默认语言(假设是中文2052)的标签
var defaultLanguageCode = 2052; // 替换成你的组织实际默认语言码
var localizedLabel = attribute.DisplayName.LocalizedLabels
    .FirstOrDefault(l => l.LanguageCode == defaultLanguageCode) 
    ?? attribute.DisplayName.LocalizedLabels.FirstOrDefault(); //  fallback到第一个存在的标签

ef.DisplayName = localizedLabel?.Label ?? attribute.LogicalName; // 最后用逻辑名兜底,避免空值

3. 强制发布所有相关元数据

有时候移除自定义字段再发布能恢复,说明之前的发布操作可能没有完全生效。可以用代码强制发布账户实体及相关表单的元数据:

// 发布所有元数据(适合快速排查)
PublishAllXmlRequest publishRequest = new PublishAllXmlRequest();
service.Execute(publishRequest);

// 或者仅发布账户实体(更精准)
PublishXmlRequest publishEntityRequest = new PublishXmlRequest
{
    ParameterXml = "<importexportxml><entities><entity>account</entity></entities></importexportxml>"
};
service.Execute(publishEntityRequest);

4. 检查自定义字段的标签配置

登录Dynamics 365后台,进入自定义字段的编辑页面,确认该字段在所有需要的语言下都配置了显示名称,至少要保证组织默认语言下有值。如果某语言的标签为空,当用户用该语言访问时,UserLocalizedLabel就会返回null。

5. 优化代码中的空值判断逻辑

原代码里的判断条件有重复,同时可以给DisplayName增加兜底逻辑,避免因为标签为空导致整个字段被过滤掉:

foreach (AttributeMetadata attribute in currentEntity.Attributes)
{
    // 简化空值判断逻辑
    if (attribute.IsValidForRead.HasValue && attribute.IsValidForRead.Value 
        && !string.IsNullOrEmpty(attribute.LogicalName)
        && _allowedFieldTypes.Contains(attribute.AttributeType.ToString().ToLower()))
    {
        EntityField ef = new EntityField();
        ef.AttributeType = attribute.AttributeType.ToString() ?? string.Empty;
        ef.IsCustomField = attribute.IsCustomAttribute ?? false;
        ef.IsAllowUpdate = attribute.IsValidForUpdate ?? false;
        ef.LogicalName = attribute.LogicalName;

        // 处理DisplayName,多层兜底
        var displayLabel = attribute.DisplayName.UserLocalizedLabel?.Label;
        if (string.IsNullOrEmpty(displayLabel))
        {
            var defaultLabel = attribute.DisplayName.LocalizedLabels.FirstOrDefault()?.Label;
            displayLabel = defaultLabel ?? attribute.LogicalName;
        }
        ef.DisplayName = displayLabel;

        // 原有选项集处理逻辑保持不变
        if (attribute.AttributeType.ToString().ToLower() == "picklist")
        {
            PicklistAttributeMetadata pm = (PicklistAttributeMetadata)attribute;
            foreach (OptionMetadata x in pm.OptionSet.Options)
            {
                ef.Items.Add(x.Label.UserLocalizedLabel?.Label ?? x.Value.ToString());
            }
        }
        else if (attribute.AttributeTypeName.Value == "MultiSelectPicklistType")
        {
            MultiSelectPicklistAttributeMetadata pm = (MultiSelectPicklistAttributeMetadata)attribute;
            foreach (OptionMetadata x in pm.OptionSet.Options)
            {
                ef.Items.Add(x.Label.UserLocalizedLabel?.Label ?? x.Value.ToString());
            }
        }

        if (Add)
        {
            fieldLst.Add(ef);
        }
    }
}

优先尝试修改RetrieveAsIfPublished参数和优化标签获取逻辑,这两个是最常见的触发原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:14:36