zoukankan      html  css  js  c++  java
  • Dynamics CRM邮件附件,你真的了解吗?

    关注本人微信和易信公众号: 微软动态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 == 1)
                {
                    Console.WriteLine("邮件的ID是" + ec.Entities[0].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[0].GetAttributeValue<Guid>("activityid")}
                                }
                            }
                        }
                    };
                    var i = 1;
                    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 == 1)
                {
                    Console.WriteLine("邮件的ID是" + ec.Entities[0].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[0].GetAttributeValue<Guid>("activityid")}
                                }
                            }
                        }
                    };
                    var i = 1;
                    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"] = 162648;//设置了这个字段的值,附件也不会显示文件大小(字节),囧
                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关联起来,附件的具体内容都是存储在这个表中的。
  • 相关阅读:
    [萌新向]在windows环境下配置基于wsl的Vim文本编辑器
    模板集合
    MATLAB:非线性规划fmincon
    Linux虚拟机网络配置
    Hyper-V 下linux虚拟机静态IP上网配置的两种方式(2)
    Hyper-V 下linux虚拟机静态IP上网配置的两种方式(1)
    centos6.5单机配置NFS
    mysql 8.0 忘记密码
    前端上传base64图片到七牛云总结
    个人作业——软件工程实践总结&个人技术博客
  • 原文地址:https://www.cnblogs.com/luoyong0201/p/Dynamics_365_Email_Attachment_ActivityMimeAttachment.html
Copyright © 2011-2022 走看看