Dynamics 365插件:处理笔记拖拽附件(msdyn_richtextfiles)问题
Dynamics 365笔记拖拽附件插件处理方案
问题1:为何msdyn_richtextfile的msdyn_fileblob是GUID而非Base64?
这是Dynamics 365富文本文件的实际存储机制导致的:当文件拖拽到笔记正文时,msdyn_fileblob字段并非直接存储Base64编码的文件内容,而是存储msdyn_storagefile实体的关联ID。官方文档的描述存在表述模糊或滞后,实际平台为优化大文件存储性能,将文件内容托管在专门的存储实体中,而非直接存在msdyn_richtextfile属性里。
问题2:获取实际文件内容需要查询哪些实体/属性?
需要通过两层关联查询:
- 先从
msdyn_richtextfile实体获取msdyn_fileblob字段(即存储实体的GUID) - 再通过该GUID查询
msdyn_storagefile实体,其msdyn_filecontent属性才是Base64编码的文件原始内容
同时,msdyn_richtextfile的msdyn_filename、msdyn_filetype字段可获取文件的名称和类型元数据。
问题3:无需调用Web API,用IOrganizationService获取的可行方案
完全可以实现,核心是通过关联查询msdyn_richtextfile和msdyn_storagefile实体,以下是插件中的示例代码:
// 1. 从annotation的notetext中解析出msdyn_richtextfile的GUID(需根据实际URL格式调整解析逻辑) string noteText = annotationEntity.GetAttributeValue<string>("notetext"); Guid richtextFileId = ExtractRichtextFileId(noteText); // 2. 查询msdyn_richtextfile,获取关联的storagefile ID QueryExpression richtextQuery = new QueryExpression("msdyn_richtextfile") { ColumnSet = new ColumnSet("msdyn_fileblob", "msdyn_filename", "msdyn_filetype"), Criteria = new FilterExpression { Conditions = { new ConditionExpression("msdyn_richtextfileid", ConditionOperator.Equal, richtextFileId) } } }; Entity richtextFile = service.RetrieveMultiple(richtextQuery).Entities.FirstOrDefault(); if (richtextFile == null) return; Guid storageFileId = richtextFile.GetAttributeValue<Guid>("msdyn_fileblob"); // 3. 查询msdyn_storagefile,获取Base64编码的文件内容 QueryExpression storageQuery = new QueryExpression("msdyn_storagefile") { ColumnSet = new ColumnSet("msdyn_filecontent"), Criteria = new FilterExpression { Conditions = { new ConditionExpression("msdyn_storagefileid", ConditionOperator.Equal, storageFileId) } } }; Entity storageFile = service.RetrieveMultiple(storageQuery).Entities.FirstOrDefault(); if (storageFile == null) return; // 4. 解码Base64得到文件字节流 string base64Content = storageFile.GetAttributeValue<string>("msdyn_filecontent"); byte[] fileBytes = Convert.FromBase64String(base64Content); // 后续将fileBytes存储到外部系统
关键注意事项
- 解析URL中的GUID时,建议用正则表达式匹配,比如
/msdyn_richtextfiles\(([0-9a-fA-F-]+)\)/来提取目标GUID - 确保插件的执行身份拥有
msdyn_richtextfile和msdyn_storagefile实体的读取权限 - 处理大文件时,注意插件的内存限制,必要时考虑分块处理逻辑
内容的提问来源于stack exchange,提问作者Peter Forsbom
相关产品推荐
相关产品推荐

