关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复160或者20151014可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!
听人问起怎么读取到一封邮件所有的附件,有人说附件也是存储在注释实体(annotation)中,我的记忆中是一个另外一个实体,SDK中有如下的原文:An activity mime attachment represents an attachment to an email message or an email template. The schema name for this entity is ActivityMimeAttachment. 这个意思中文翻译过来就是,一个ActivityMimeAttachment 实体记录代表着一个邮件或者一个邮件模板的附件。众说纷纭,但是实践出真知,让我用一个有图有真相的博文来说明下吧。
我们先来查看下元数据吧,这个实体的中文显示名称是 附件,但是元数据中还有另外一个实体的显示名称也叫附件,这个实体的架构名称是 Attachment ,描述是 电子邮件活动的附件。从本博文后面可以知道,邮件附件的文件信息是存储在这个实体中,那么注释的附件内容是不是存储在这个实体中呢?下片博文(Dynamics CRM中的注释(Note)及RollupRequest消息初探)再实践验证。我将这个实体(ActivityMimeAttachment)的字段属性截图放在下面:值得注意的是这个实体的 IsValidForAdvancedFind 是false,也就是不会出现在高级查询中。
我们先通过快速创建一封邮件。
邮件大致内容如下,注意我为本邮件上传了一个附件,名称为 logo.png,其实就是素格格新疆特产店的logo:
然后我参考下SDK中的章节 Sample: Create, retrieve, update, and delete an email attachment ,Sample: Retrieve email attachments for an email template 等, 使用了如下的代码:
        static void Main(string[] args)
{
var service = GetOrganizationService();
var fetchXML = string.Format(@"<fetch mapping='logical' output-format='xml-platform' version='1.0' distinct='false' no-lock='true' count='1'>
<entity name='email'>
<attribute name='subject' />
<attribute name='regardingobjectid' />
<attribute name='from' />
<attribute name='to' />
<attribute name='statuscode' />
<attribute name='activityid' />
<filter type='and'>
<condition value='微软MVP罗勇测试附件的邮件主题' attribute='subject' operator='eq' />
</filter>
</entity>
</fetch>");
EntityCollection ec = service.RetrieveMultiple(new FetchExpression(fetchXML));
if (ec.Entities.Count == )
{
Console.WriteLine("邮件的ID是" + ec.Entities[].GetAttributeValue<Guid>("activityid") + "下面是附件信息:");
QueryExpression query = new QueryExpression
{
EntityName = "activitymimeattachment",
ColumnSet = new ColumnSet("filename","subject","filesize","mimetype","activityid","activitymimeattachmentid","body"),
Criteria =
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression
{
AttributeName = "objecttypecode",
Operator = ConditionOperator.Equal,
Values = {"email"}
},
new ConditionExpression
{
AttributeName = "objectid",
Operator = ConditionOperator.Equal,
Values = {ec.Entities[].GetAttributeValue<Guid>("activityid")}
}
}
}
};
var i = ;
foreach (var entity in service.RetrieveMultiple(query).Entities)
{
Console.WriteLine("第" + i + "个附件:");
Console.WriteLine("filename:" + entity.GetAttributeValue<string>("filename"));
Console.WriteLine("filesize:" + entity.GetAttributeValue<int>("filesize"));
Console.WriteLine("mimetype:" + entity.GetAttributeValue<string>("mimetype"));
Console.WriteLine("subject:" + entity.GetAttributeValue<string>("subject"));
Console.WriteLine("activityid:" + entity.GetAttributeValue<EntityReference>("activityid").Id);
Console.WriteLine("activitymimeattachmentid:" + entity.GetAttributeValue<Guid>("activitymimeattachmentid"));
Console.WriteLine("body:" + entity.GetAttributeValue<string>("body"));
Console.WriteLine("--------------------------------------------------"); i++;
}
}
Console.WriteLine("程序运行完成!");
Console.ReadKey();
}

运行结果如下,可以得知filesize应该是以字节为单位的,附件的内容应该是以base64编码后存储等等信息:

当然如果有多个附件也是可以得,我去掉了读取显示body字段,运行结果如下:
我发现一个问题,就是这两个附件的 activityid 字段值是相同的,那么我可以用这个条件来查询出一个邮件的所有附件吗?试试看,代码如下:
       static void Main(string[] args)
{
var service = GetOrganizationService();
var fetchXML = string.Format(@"<fetch mapping='logical' output-format='xml-platform' version='1.0' distinct='false' no-lock='true' count='1'>
<entity name='email'>
<attribute name='subject' />
<attribute name='regardingobjectid' />
<attribute name='from' />
<attribute name='to' />
<attribute name='statuscode' />
<attribute name='activityid' />
<filter type='and'>
<condition value='微软MVP罗勇测试附件的邮件主题' attribute='subject' operator='eq' />
</filter>
</entity>
</fetch>");
EntityCollection ec = service.RetrieveMultiple(new FetchExpression(fetchXML));
if (ec.Entities.Count == )
{
Console.WriteLine("邮件的ID是" + ec.Entities[].GetAttributeValue<Guid>("activityid") + "下面是附件信息:");
QueryExpression query = new QueryExpression
{
EntityName = "activitymimeattachment",
ColumnSet = new ColumnSet("filename","subject","filesize","mimetype","activityid","activitymimeattachmentid"),
Criteria =
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression
{
AttributeName = "activityid",
Operator = ConditionOperator.Equal,
Values = {ec.Entities[].GetAttributeValue<Guid>("activityid")}
}
}
}
};
var i = ;
foreach (var entity in service.RetrieveMultiple(query).Entities)
{
Console.WriteLine("第" + i + "个附件:");
Console.WriteLine("filename:" + entity.GetAttributeValue<string>("filename"));
Console.WriteLine("filesize:" + entity.GetAttributeValue<int>("filesize"));
Console.WriteLine("mimetype:" + entity.GetAttributeValue<string>("mimetype"));
Console.WriteLine("subject:" + entity.GetAttributeValue<string>("subject"));
Console.WriteLine("activityid:" + entity.GetAttributeValue<EntityReference>("activityid").Id);
Console.WriteLine("activitymimeattachmentid:" + entity.GetAttributeValue<Guid>("activitymimeattachmentid"));
Console.WriteLine("--------------------------------------------------");
i++;
}
}
Console.WriteLine("程序运行完成!");
Console.ReadKey();
}
测试结果表明是可以的,后面邮件使用了现有附件以后我也进行了测试,也是可以得。
下面介绍下重复利用附件,也就是新邮件使用现有附件,我先用代码创建一封邮件,然后把现有的附件附加到新建的邮件:
        static void Main(string[] args)
{
var service = GetOrganizationService();
WhoAmIRequest whoAmIRequest = new WhoAmIRequest();
WhoAmIResponse whoAmIResponse = service.Execute(whoAmIRequest) as WhoAmIResponse;
Entity fromEntity = new Entity("activityparty");
fromEntity["partyid"] = new EntityReference("systemuser", whoAmIResponse.UserId);
Entity toEntity = new Entity("activityparty");
toEntity["partyid"] = new EntityReference("account", new Guid("858AB47F-494A-E511-80D2-000D3A802FAC"));
Entity emailEntity = new Entity("email");
emailEntity["to"] = new Entity[] { toEntity };
emailEntity["from"] = new Entity[] { fromEntity };
emailEntity["subject"] = "微软MVP罗勇测试邮件使用现有附件";
emailEntity["description"] = "<a href='http://sugege.top'>素格格新疆特产店</a>";
var emailId = service.Create(emailEntity);
var activityMimeAttachment = new Entity("activitymimeattachment");
activityMimeAttachment["objectid"] = new EntityReference("email",emailId);
activityMimeAttachment["objecttypecode"] = "email";
activityMimeAttachment["filename"] = "sugege.png";//不设置这个字段的值,附件不会显示文件名
activityMimeAttachment["filesize"] = ;//设置了这个字段的值,附件也不会显示文件大小(字节),囧
activityMimeAttachment["attachmentid"] = new Guid("b8ef5a55-1872-e511-80e6-000d3a804b9b");//该字段不能使用new EntityReference类型来赋值
service.Create(activityMimeAttachment);
Console.WriteLine("程序运行完成!");
Console.ReadKey();
}
代码运行结果是新增了一个邮件如下:这里有个问题就是,你双击打开这个邮件附件会看不到附件内容,而是一个上传附件的窗口给你,这和普通的使用新建附件不同,这个做的不好。
 
但是我如果查询这个邮件的附件信息会发现有点儿不同,比如filesize为0,mimetype为空值,囧。
 
那你可能会问如果邮件附件不是现有的附件,而是新建上传的附件,会不会有同样的问题,我们用代码来测试下:
       static void Main(string[] args)
{
var service = GetOrganizationService();
WhoAmIRequest whoAmIRequest = new WhoAmIRequest();
WhoAmIResponse whoAmIResponse = service.Execute(whoAmIRequest) as WhoAmIResponse;
Entity fromEntity = new Entity("activityparty");
fromEntity["partyid"] = new EntityReference("systemuser", whoAmIResponse.UserId);
Entity toEntity = new Entity("activityparty");
toEntity["partyid"] = new EntityReference("account", new Guid("858AB47F-494A-E511-80D2-000D3A802FAC"));
Entity emailEntity = new Entity("email");
emailEntity["to"] = new Entity[] { toEntity };
emailEntity["from"] = new Entity[] { fromEntity };
emailEntity["subject"] = "微软MVP罗勇测试邮件使用新附件";
emailEntity["description"] = "<a href='http://sugege.top'>素格格新疆特产店</a>";
var emailId = service.Create(emailEntity);
var activityMimeAttachment = new Entity("activitymimeattachment");
activityMimeAttachment["objectid"] = new EntityReference("email", emailId);
activityMimeAttachment["objecttypecode"] = "email";
activityMimeAttachment["subject"] = "附件示例";
activityMimeAttachment["filename"] = "mvpluoyong.txt";//不设置这个字段的值,附件不会显示文件名
activityMimeAttachment["body"] = System.Convert.ToBase64String(new UTF8Encoding().GetBytes(@"微软MVP罗勇测试邮件使用新附件"));
service.Create(activityMimeAttachment);
Console.WriteLine("程序运行完成!");
Console.ReadKey();
}
产生的邮件如下:
 
查询结果如下,可以知道查询出来的结果是齐的了,双击打开附件也是可以看到附件内容的,比用现有附件好。
表面上的说完了,我们稍微理解下在系统中是如何存储的,实体ActivityMimeAttachment在数据库中对应了一个表activitymimeattachment,但是这个表并没有存储附件的文件名,大小,内容等信息,而是这个表activitymimeattachment 通过 AttachmentId字段和另外一个实体Attachment对应的表Attachment关联起来,附件的具体内容都是存储在这个表中的。

Dynamics CRM邮件附件,你真的了解吗?的更多相关文章

  1. dynamics crm 365 附件上传图片并且显示。

    参考了几篇博客做的: 新增websource文件(html): <!DOCTYPE html> <html> <head> <title>注释</ ...

  2. Dynamics CRM中的注释(Note)及RollupRequest消息初探

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复161或者20151015可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 注释,这个实体的架构名称是Ann ...

  3. Dynamics CRM 2013开始推出的服务器端同步来配置邮件服务

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  4. 为Dynamics CRM的Office附件注释定制个无需下载即可在线查看的功能

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复164或者20151021可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 上一篇博客:为Dynamics ...

  5. 为Dynamics CRM注释的图片附件做个预览功能

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复163或者20151017可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! Dynamics CRM中注释可 ...

  6. Dynamics CRM 2016 的新特性

    新版本CRM (2016 with update 0.1) 发布已有几个月了,总结一下新特性,从几个方面来看: 1. 针对整合功能的新特性 (1) 增加了CRM App for Outlook. 这个 ...

  7. Dynamics CRM中的操作(action)是否是一个事务(transaction)?

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复168或者20151104可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 以前的博文 微软Dynamics ...

  8. C# MailMessage Attachment 中文名附件发邮件-Firefox中文显示正常,网页打开邮件附件中文名乱码

    一.故事 首先通过CDO.Message来获取邮件EML相关数据:邮件标题.邮件内容.邮件附件.发件人.收件人.CC主要就这么几个,其次通过MailMessage来组织邮件通过Python来发送邮件! ...

  9. Dynamics CRM模拟OAuth请求获得Token后在外部调用Web API

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复233或者20161104可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

随机推荐

  1. Fragment中不能使用自定义带参构造函数

    通过Fragment自定义的静态方法将值从activity传到fragment中,然后就想到这样不是多次一举吗,为什么不直接写个带参构造函数将值传过去呢?试了一下,发现Fragment有参构造函数竟然 ...

  2. IO测试工具 - 用于IO测试 ; linux benchmarks

    IO测试工具,用于磁盘IO测试,下面进行使用列表进行记录: iozone fio dd ioping iotop iostat bonnie++ crystalDisk Atto as-ssd-ben ...

  3. 如何把Mybatis的Mapper.xml配置文件和dao接口放在同一个包下

    有的时候我们在Maven项目中写关于Mybatis的项目时,会涉及到很多的实体类,也就会涉及到很多的dao接口,如果此时我们仍然把dao接口和xml写在同一个包下,会让项目接口变得很乱,杂七杂八的,所 ...

  4. Java中数组与集合的相互转换

    数组与List的相互转换 List转数组:采用集合的toArray()方法 数组转List:采用Arrays的asList()方法 数组转换为集合 注意:在数组转集合的过程中,要注意是否使用了视图的方 ...

  5. Linux Bash文本操作之sed篇其一

    作为Linux系统中文本处理的强力工具之一,sed功能强大,用法多变,值得我们好好学习. sed是用于过滤和转换文本的流编辑器. 一般情况下sed把当前处理的行存储在临时缓冲区,按指定命令处理之后将缓 ...

  6. Centos 中使用通过docker 部署.netcore

    此前,我一直觉得,目前网络上的各种各样的技术文章.技术文档已经足够多,任何一种技术,都可以或多或少的在网络上找到教程,或者在qq群里找到前辈解答.所以,我觉得自己在博客上写文章的意义甚少.甚至觉得自己 ...

  7. 【CF528D】Fuzzy Search

    Problem Description 你有一个长度为 \(n\) 的串 \(S\),以及长度为 \(m\) 的串 \(T\). 现给定一个数 \(k\) ,我们说 \(T\) 在 \(S\) 的位置 ...

  8. SAP 下钻功能大全

    FORM ALV_USER_COMMAND USING R_UCOMM LIKE SY-UCOMM "作为reuse_alv_grid_display的事件i_callback_user_c ...

  9. 遇见手绘花卉小清新简约通用PPT模板推荐

    模版来源:http://ppt.dede58.com/jiaoxuekejian/26484.html

  10. 前端开发规范:3-CSS

    尽量使用缩写属性 border-top-style: none; font-family: palatino, georgia, serif; font-size: 100%; line-height ...