【问题标题】:Copying annotations leads to a corrupted attachment复制注释会导致附件损坏
【发布时间】:2014-05-06 14:37:46
【问题描述】:

我正在实现一个插件(POST Quote Create、Synchronous、Sandbox),以便在修改报价时将注释复制到新记录中。

我的插件归结为这个(sn-p):

var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var Service = serviceFactory.CreateOrganizationService(context.UserId);

var notesQuery = new QueryExpression("annotation");
notesQuery.ColumnSet = new ColumnSet(true);
notesQuery.Criteria = new FilterExpression
{
    FilterOperator = LogicalOperator.And,
    Conditions =
    {
        new ConditionExpression("objecttypecode", ConditionOperator.Equal, "quote"),
        new ConditionExpression("objectid", ConditionOperator.Equal, revisedQuoteId)
    }
};
var notes = Service.RetrieveMultiple(notesQuery).Entities;
foreach (var n in notes)
{
    var newNote = new Entity("annotation");

    newNote.Attributes.Add("ownerid", n.GetAttributeValue<EntityReference>("ownerid"));

    newNote.Attributes.Add("objectid", new EntityReference("quote", sourceEntity.Id));
    newNote.Attributes.Add("objecttypecode", "quote");

    newNote.Attributes.Add("subject", n.GetAttributeValue<string>("subject"));
    newNote.Attributes.Add("notetext", n.GetAttributeValue<string>("notetext"));

    newNote.Attributes.Add("isdocument", n.GetAttributeValue<bool>("isdocument"));

    if (n.GetAttributeValue<bool>("isdocument"))
    {
        newNote.Attributes.Add("filesize", n.GetAttributeValue<int>("filesize"));
        newNote.Attributes.Add("documentbody", n.GetAttributeValue<string>("documentbody"));
        newNote.Attributes.Add("filename", n.GetAttributeValue<string>("filename"));
        newNote.Attributes.Add("mimetype", n.GetAttributeValue<string>("mimetype"));
    }

    Service.Create(newNote);
}

基本上,我会复制所有内容,包括最终的附件。一切似乎都很好,新版本正确地显示了字段、详细记录和注释……除了注释的附件之外的所有内容。

如果我有一个笔记,附上test.txt,内容是:

测试附件

OrganizationData 服务内容如下:

<d:FileName>test.txt</d:FileName>
<d:FileSize m:type="Edm.Int32">39</d:FileSize>        
<d:DocumentBody>H4sIAAAMaVMA/wtJLS5RSCwpSUzOyE3NK+HlAgCLmj1zEQAAAA==</d:DocumentBody>

它的“克隆”具有正确的主题和文本,并且还显示了一个test.txt 附加的内容是什么

‹ iS ÿI-.QH,)ILÎÈMÍ+áå ‹š=s

mimetype filesize(在检查odata时,我注意到filesize实际上正确!)似乎是正确的(又名:相同作为我试图复制的原始注释),但 OData 似乎确认了某些东西已经关闭(它不同!):

<d:FileName>test.txt</d:FileName>
<d:FileSize m:type="Edm.Int32">60</d:FileSize
<d:DocumentBody>H4sIAED6aVMA/5Pv5mBg4MkMZvjP7amrF+iho+npc+6E71nth0+ZGLpn2RYLMjAwAABXqCwTJQAAAA==</d:DocumentBody>

test.txt 文件是从命令提示符创建的(COPY CON test.txt,键入,CTRL+Z)。

我尝试更改文件,并通过 PDFCreator 创建了一个test.pdf:AcroRead 反过来抱怨说文档已损坏(因此问题似乎与 mimetype 无关)。

我还尝试通过早期绑定(通过 CRMSVCUTIL 生成的类)重新实现相同的代码,但它会产生完全相同的结果(垃圾而不是附件内容)。

我尝试像这样手工制作documentbody

// "VGVzdCBhdHRhY2htZW50" is Base64 for "Test attachment"
newNote.Attributes.Add("documentbody", "VGVzdCBhdHRhY2htZW50");

而且创建的文件是正确的

我不知道发生了什么:据我所知,documentbody 应该是一个 Base64 编码的字符串(同样,据我所知)复制时应该没有任何不同.我错过了什么?

作为参考,CRM 已更新为 UR13,但我在 UR16 环境中重新制作了它。

【问题讨论】:

  • 你检查过n.GetAttributeValue&lt;string&gt;("documentbody")的值,并尝试解码检查内容吗?
  • 我在问题中整合了我以前的 cmets。最新添加:早期绑定的代码做同样的事情会产生同样的结果

标签: c# plugins encoding dynamics-crm-2011


【解决方案1】:

编辑:不起作用(仅适用于 CRM 4)

试试这个(未验证):

var notes = Service.RetrieveMultiple(notesQuery).Entities;
foreach (var newNote in notes)
{
    newNote.annotationid = null;

    newNote.Attributes.Add("objectid", new EntityReference("quote", sourceEntity.Id));
    newNote.Attributes.Add("objecttypecode", "quote");

    Service.Create(newNote);
}

【讨论】:

  • CRM 似乎不喜欢这种方法(检索记录、清除 id、更改 objectid、重新创建),我得到“无效参数”(如果我取消 id)或“重复错误"(如果我从 newNote 中删除 id 属性,以及 createdon、modifiedon 等)
  • base64 编码的字符串“测试附件”是“VGVzdCBhdHRhY2htZW50”。您可以尝试(仅出于测试目的以缩小错误原因)newNote.Attributes.Add("documentbody","VGVzdCBhdHRhY2htZW50");
  • 顺便说一句:文件大小也很奇怪。 “测试附件”长度为 15 个字符,因此,如果是 ascii 编码,则包含此内容的文件大约为 15 个字节,如果是 utf8 编码,则为 18 个字节,如果是 utf-16 编码,则为 32 个字节。 39 或 60 字节的文件大小似乎不是废话。
  • 像这样手工制作的文档正文在便笺中产生了正确的文件内容。我还在 UR16 环境中重现了该问题(修正问题)。我同意奇怪的文件大小,但我在这里不知所措
  • 好的,那么出于什么原因,语句 n.GetAttributeValue("documentbody") ,这意味着源注释,已经返回垃圾。也许您可以通过跟踪服务打印出值(或将值存储在 crm ui 中可见的文本字段中)。此外,您可以使用 sql managementstudio 查看存储在 documentbody 字段中的数据库。另一个问题是确定:执行插件的用户是否允许读取文档正文字段(检查字段级安全首选项)?
【解决方案2】:

刚刚在 MSDN 的一篇文章中看到了这一点:

Annotation setupAnnotation = new Annotation()
{
  Subject = "Example Annotation",
  FileName = "ExampleAnnotationAttachment.txt",
  DocumentBody = Convert.ToBase64String(
  new UnicodeEncoding().GetBytes("Sample Annotation Text")),
  MimeType = "text/plain"
};

我看到文档正文是根据 Unicode 编码进行编码的。也许您应该尝试从文件中检索编码并相应地将其转换为字符串。

【讨论】:

    猜你喜欢
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 2021-07-26
    • 1970-01-01
    相关资源
    最近更新 更多