【问题标题】:Parse/deserialize MTOM/XOP Data .NET解析/反序列化 MTOM/XOP 数据 .NET
【发布时间】:2013-04-08 07:27:13
【问题描述】:

如何解析/反序列化使用 WCF 从 Web 服务获得的 MTOM/XOP 响应?我在磁盘上有响应。我已复制以下回复:

Date: Wed, 02 May 2012 09:38:57 GMT
Server: Microsoft-IIS/6.0
P3P:CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
X-WindowsLive-Hydra: H: BLU165-ds6 V: 16.3.133.328 D: 2012-03-29T02:31:31
X-Response-Time: 78.1245
X-TransactionID: d491414e-46fd-47b2-82ce-e9cea9f564aa;BLU165-ds6;16.3.133.328;2012-05-02 09:38:57 UTC;78.1245 ms
Set-Cookie: HMDST=dGVhcG90ZG9tZYtZm3GzLm1r3f+/q8+gdzrAPYmy9kJ+SmDZuFmVgk3E983xNyeoTZkkdIr6t8y3P4V+vPzmytdaqqFwtI8vBuc=; domain=.mail.services.live.com; path=/
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/xop+xml
Content-Length: 6386

MIME-Version: 1.0
Content-Type: Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM;
    type="application/xop+xml";
    start="<DeltaSyncMTOMFetchResponse@mail.services.live.com>";

--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM
content-transfer-encoding: binary
content-type: application/xop+xml; charset=utf-8; type="application/xop+xml"
content-id: <DeltaSyncMTOMFetchResponse@mail.services.live.com>

<ItemOperations xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:B="HMMAIL:" xmlns:D="HMSYNC:" xmlns="ItemOperations:"><Status>1</Status><Responses><Fetch><ServerId>E631966A-9439-11E1-8E7B-00215AD9A7B8</ServerId><Status>1</Status><Message><xop:Include href="cid:1.634715231374437235@example.org" /></Message></Fetch></Responses></ItemOperations>
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM
content-transfer-encoding: binary
content-type: application/octet-stream
content-id: <1.634715231374437235@example.org>

....Binary Content
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM--

非常感谢任何帮助。

【问题讨论】:

  • 回复:There must be a class/method that does what I am trying? 那不是很好。可悲的是,MS 说他们在 MTOM 实施中不做附件。没有定义访问cid 或其内容的方法。我正在开发一个可以处理此问题的扩展类(通过颠覆通道并手动解析返回的 MTOM)。如果我想出任何功能性,我会告诉你的。但不要屏住呼吸优雅
  • 永远不会屏住呼吸这么久!
  • @user349026 - 你可能需要再坚持一会儿。 :( 原来我实施的是公司财产(根据律师的说法)。我将不得不在我自己的时间和计算机上重新发明它,与我原来的完全不同,以便能够在这里发布它。

标签: c# xml wcf deserialization mtom


【解决方案1】:

您可以使用 WCF 类反序列化响应,如下所示。但在我们继续之前,此 MTOM 无效 - Content-Type 标头的参数 boundary 格式错误。因为它包含“?”字符,它需要被引用(查看MIME RFC,第 5.1 节,token 的定义)。

现在,要对其进行反序列化,您需要使用 MTOM 阅读器打开文档 - 而XmlDictionaryReader.CreateMtomReader 将为您提供准确的信息。创建该阅读器后,您可以将其传递给DataContractSerializer 以反序列化对象。下面的代码展示了如何做到这一点。

    public class StackOverflow_10531128
    {
        const string MTOM = @"MIME-Version: 1.0
Content-Type: Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM;
    type=""application/xop+xml"";
    start=""<DeltaSyncMTOMFetchResponse@mail.services.live.com>"";

--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM
content-transfer-encoding: binary
Content-Type: application/xop+xml; charset=utf-8; type=""application/xop+xml""
content-id: <DeltaSyncMTOMFetchResponse@mail.services.live.com>

<ItemOperations xmlns:xop=""http://www.w3.org/2004/08/xop/include"" xmlns:B=""HMMAIL:"" xmlns:D=""HMSYNC:"" xmlns=""ItemOperations:"">
    <Status>1</Status>
    <Responses>
        <Fetch>
            <ServerId>E631966A-9439-11E1-8E7B-00215AD9A7B8</ServerId>
            <Status>1</Status>
            <Message><xop:Include href=""cid:1.634715231374437235@example.org"" /></Message>
        </Fetch>
    </Responses>
</ItemOperations>
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM
content-transfer-encoding: binary
Content-Type: application/octet-stream
content-id: <1.634715231374437235@example.org>

this is a binary content; it could be anything but for simplicity I'm using text
--DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM--";

        [DataContract(Name = "ItemOperations", Namespace = "ItemOperations:")]
        public class ItemOperations
        {
            [DataMember(Order = 1)]
            public int Status { get; set; }
            [DataMember(Order = 2)]
            public Responses Responses { get; set; }
        }

        [CollectionDataContract(Name = "Responses", Namespace = "ItemOperations:", ItemName = "Fetch")]
        public class Responses : List<Fetch>
        {
        }

        [DataContract(Name = "Fetch", Namespace = "ItemOperations:")]
        public class Fetch
        {
            [DataMember(Order = 1)]
            public Guid ServerId { get; set; }
            [DataMember(Order = 2)]
            public int Status { get; set; }
            [DataMember(Order = 3)]
            public byte[] Message { get; set; }
        }

        public static void Test()
        {
            MemoryStream ms;
            ItemOperations obj;
            DataContractSerializer dcs = new DataContractSerializer(typeof(ItemOperations));

            string fixedMtom = MTOM.Replace(
                "Multipart/Related;boundary=DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM;",
                "Multipart/Related;boundary=\"DeltaSync91ABCB4AF5D24B8F988B77ED7A19733D?MTOM\";");
            ms = new MemoryStream(Encoding.UTF8.GetBytes(fixedMtom));
            XmlDictionaryReader reader = XmlDictionaryReader.CreateMtomReader(ms, Encoding.UTF8, XmlDictionaryReaderQuotas.Max);
            obj = (ItemOperations)dcs.ReadObject(reader);
            Console.WriteLine(obj.Status);
            Console.WriteLine(obj.Responses.Count);
            foreach (var resp in obj.Responses)
            {
                Console.WriteLine("  {0}", resp.ServerId);
                Console.WriteLine("  {0}", resp.Status);
                Console.WriteLine("  {0}", string.Join(" ", resp.Message.Select(b => string.Format("{0:X2}", (int)b))));
            }
        }
    }

【讨论】:

  • 如果 MTOM 具有图像的二进制流,并且如您的示例中将其转换为字符串,那会破坏流吗?
  • 这是一个简单的示例,展示了如何使用 WCF 类读取 MTOM 文档,为了使其完整和独立,我将 MTOM“文档”硬编码为文件中的字符串。通常会发生的情况是从某些外部源(文件、网络等)读取文档,并且字节会被正确编码(并且会被 MTOM 阅读器正确读取)。
  • 如何在 C# 核心中做同样的事情?
猜你喜欢
  • 2020-03-16
  • 2013-08-11
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 2012-01-23
  • 2016-07-18
  • 2020-09-28
  • 2015-09-21
相关资源
最近更新 更多