为什么我不能反序列化我的对象,如果它包含XML变得稍大?(Why can't I deser

2019-10-19 11:47发布

我有试图将消息发送到使用REST API在Azure服务总线的问题,并把它使用.NET蔚蓝服务总线客户端API类好评。 我可以高兴地发送和接收单独使用SDK使用这些对象的消息,但试图使用REST API时,你得到的问题。

我已经缩小的问题降到这个最小的摄制,我认为。 基本上,如果我我的序列化对象与XML的小amoutn作为有效载荷你的一切工作正常。 如果我添加稍微XML,然后我得到一个异常反序列化它。 这应该剪切和粘贴到一个新的控制台应用程序,允许发行摄制:

using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml;
using System.Xml.Linq;
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        GetMessageBytes(Guid.NewGuid());
    }

    private static byte[] GetMessageBytes(Guid requestId)
    {
        var payload = XElement.Parse(@"
<blah Type='TransactionRequest' Version='1' xmlns=''>
    <SomeData Type='Request' Selection='All'></SomeData>
</blah>");

        var invalidPayload = XElement.Parse(@"
<blah Type='TransactionRequest' Version='1' xmlns=''>
    <SomeData Type='Request' Selection='All'></SomeData>
    <SomeData Type='Request' Selection='All'></SomeData>
    <SomeData Type='Request' Selection='All'></SomeData>
    <SomeData Type='Request' Selection='All'></SomeData>
    <SomeData Type='Request' Selection='All'></SomeData>
</blah>");
        Message<XElement> message = new Message<XElement>()
        {
            Label = "Label",
            RequestId = requestId,
            Payload = payload
        };

        var messageBytes = EncodeMessage(message);
        var expectedResponse = DecodeMessage<Message<XElement>>(messageBytes);

        message = new Message<XElement>()
        {
            Label = "Label",
            RequestId = requestId,
            Payload = invalidPayload
        };

        messageBytes = EncodeMessage(message);
        expectedResponse = DecodeMessage<Message<XElement>>(messageBytes);
        Console.WriteLine(expectedResponse);
        return messageBytes;
    }

    private static byte[] EncodeMessage<T>(T message)
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        var memoryStream = new MemoryStream();
        XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(memoryStream);
        serializer.WriteObject(binaryDictionaryWriter, message);
        binaryDictionaryWriter.Flush();
        var bytesToPost = memoryStream.GetBuffer();
        return bytesToPost;
    }

    private static T DecodeMessage<T>(byte[] response)
    {
        var ms = new MemoryStream(response);
        var serializer = new DataContractSerializer(typeof(T));
        XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(ms, XmlDictionaryReaderQuotas.Max);

        var message = serializer.ReadObject(binaryDictionaryReader);
        return (T)message;
    }
}

[MessageContract(WrapperName = "Message", WrapperNamespace = "http://blah.co.uk/contracts", IsWrapped = true)]
public sealed class Message<T>        where T : class
{
    [MessageHeader(Namespace = "http://blah.co.uk/contracts", Name = "RequestId")]
    public Guid RequestId { get; set; }

    [MessageHeader(Namespace = "http://blah.co.uk/contracts", Name = "Label")]
    public string Label { get; set; }

    [MessageBodyMember(Namespace = "http://blah.co.uk/contracts", Name = "Payload")]
    public T Payload { get; set; }

    [MessageBodyMember(Namespace = "http://blah.co.uk/contracts", Name = "MonitoringResults")]
    public MessageTimestamp MessageTimestamp { get; set; }


}

[DataContract]
public class MessageTimestamp
{
    private ICollection<Timestamp> timestamps = new List<Timestamp>();

    [DataMember]
    public ICollection<Timestamp> GetAllTimestamps
    {
        get
        {
            return timestamps.ToList();
        }

        private set
        {
            timestamps = new List<Timestamp>(value);
        }
    }        
}

public class Timestamp
{
    public Operation Operation { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }

    public TimeSpan TimeTaken
    {
        get
        {
            return EndTime - StartTime;
        }
    }
}

public enum Operation
{
    OverallProcessing
}

时引发的错误是:

时发生错误,反序列化类型的对象SerialisationIssue.Message 1 [[System.Xml.Linq.XElement,System.Xml.Linq的,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089]]`。 输入源的格式不正确。

我曾尝试连载大量的只是XML的(即没有Message<XElement>包装),并且工作正常,所以我敢肯定,它不是真正相关的XML的大小,但是,始终使其破裂。

我已经反映在ServiceBus SDK客户端库使用,并试图利用在那里(DataContractBinarySerializer)发现解串器的实际类,但已经没有什么区别,似乎基本上做到这一点,我做手工反正同样的事情。

我如何能找到真正的问题是什么什么想法? 怎么我可能会去修复它?

Answer 1:

所以这个问题确实涉及到的一些明显错误XmlBinaryReader在此列出连接问题

这可以通过在序列化数据的末尾写入一些空白被合作周围,在提出这个帖子



文章来源: Why can't I deserialize my object if the xml it contains gets slightly larger?