如何通过C#插件使Dynamics 365 CRM自定义字段在UI可见
问题解决:Dynamics 365 CRM自定义字段UI不可见及SavedQuery错误
一、"找不到类型或命名空间名称'SavedQuery'"错误原因及解决
该错误源于未引用对应实体类,且当前Dynamics 365 SDK更推荐直接使用Entity类操作savedquery实体(SavedQuery的逻辑名称为savedquery),无需依赖特定实体类。
二、完整修正代码
以下代码包含创建自定义字段、生成含该字段的公共视图、发布元数据的完整逻辑,可解决字段UI不可见及类型错误问题:
using System; using System.Configuration; using System.Net; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Metadata; using Microsoft.Xrm.Tooling.Connector; namespace ConnectD365Crm { public class Program { static void Main(string[] args) { IOrganizationService service = GetCrmService(); CreateFieldAndUpdateView(service); } public static IOrganizationService GetCrmService() { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; string connectionString = ConfigurationManager.ConnectionStrings["CRMConnectionString"].ConnectionString; CrmServiceClient serviceClient = new CrmServiceClient(connectionString); if (!serviceClient.IsReady) { throw new Exception(serviceClient.LastCrmError); } IOrganizationService organizationService = serviceClient.OrganizationWebProxyClient != null ? (IOrganizationService)serviceClient.OrganizationWebProxyClient : (IOrganizationService)serviceClient.OrganizationServiceProxy; return organizationService; } public static void CreateFieldAndUpdateView(IOrganizationService service) { // 1. 创建自定义字符串字段 StringAttributeMetadata stringAttribute = new StringAttributeMetadata { SchemaName = "new_jobcity", DisplayName = new Label("工作城市", 1033), RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None), Description = new Label("填写你的工作城市", 1033), MaxLength = 100 }; CreateAttributeRequest createAttributeRequest = new CreateAttributeRequest { EntityName = "contact", Attribute = stringAttribute }; service.Execute(createAttributeRequest); // 2. 创建包含新字段的公共视图 string layoutXml = @"<grid name='resultset' object='2' jump='name' select='1' preview='1' icon='1'> <row name='result' id='contactid'> <cell name='name' width='150' /> <cell name='new_jobcity' width='150' /> </row> </grid>"; string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'> <entity name='contact'> <order attribute='fullname' descending='false' /> <attribute name='fullname' /> <attribute name='new_jobcity' /> <attribute name='contactid' /> </entity> </fetch>"; // 使用Entity类构造SavedQuery实体,避免类型引用问题 Entity savedQuery = new Entity("savedquery") { ["name"] = "自定义联系人工作城市视图", ["description"] = "代码创建的包含工作城市字段的公共视图", ["returnedtypecode"] = "contact", ["fetchxml"] = fetchXml, ["layoutxml"] = layoutXml, ["querytype"] = new OptionSetValue(0) // 0代表公共视图 }; service.Create(savedQuery); // 3. 发布所有元数据,确保更改生效 PublishAllXmlRequest publishRequest = new PublishAllXmlRequest(); service.Execute(publishRequest); } } }
三、关键修正点说明
- 替换SavedQuery类为Entity:直接通过
Entity("savedquery")构造视图实体,无需额外引用命名空间,彻底解决类型找不到的错误。 - 修正RequiredLevel赋值:原代码未指定枚举类型,改为
AttributeRequiredLevel.None,符合语法规范。 - 优化FetchXml排序:将排序字段改为
fullname(联系人全名),更贴合业务逻辑。 - 添加连接有效性检查:通过
serviceClient.IsReady判断CRM连接状态,避免无效操作。
四、确保字段在表单中可见的额外操作
如果需要让字段在联系人表单(而非仅列表视图)中显示,可选择两种方式:
- 代码方式:使用
UpdateEntityRequest或InsertFormXmlRequest修改表单布局XML,将字段添加到指定表单节。 - 手动方式:进入CRM>高级设置>自定义>联系人>表单>打开主表单>将"工作城市"字段拖拽到合适位置>保存并发布。
内容的提问来源于stack exchange,提问作者Avijit Paul Poddar
相关产品推荐
相关产品推荐

