XmlSerializer错误,字节数组,List和InvalidOperationException

时间:2016-02-17 19:10:18

标签: c# xml xmlserializer mtom

我在C#中发现了一个奇怪的XmlSerializer行为,有人帮助我吗? 我想在SOAP / MTOM中使用这个XML,我需要xop:包含在任何其他XMLElement之外:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xop:Include href="cid:http://tempuri.org/1/635913361387292553" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
    <List>1</List>
    <List>2</List>
</Root>

这是我的C#代码:

public static void Main(string[] args)
{
    var simulatedFile = new byte[800];
    new Random().NextBytes(simulatedFile);
    var root = new Root {List = new List<string> {"1","2"}, Bytes = simulatedFile};

    XmlSerializer ser = new XmlSerializer(typeof(Root));
    using (var mtomInMemory = new MemoryStream())
    {
        using (var writer = XmlDictionaryWriter.CreateMtomWriter(mtomInMemory, Encoding.UTF8, int.MaxValue, string.Empty))
        {
            ser.Serialize(writer, root);
        }
        Console.WriteLine(Encoding.UTF8.GetString(mtomInMemory.ToArray()));
    }

    Console.Read();
}
public class Root
{
    [XmlText]
    public byte[] Bytes { get; set; }
    [XmlElement]
    public List<string> List { get; set; }
}

我遇到的错误是:

  

&#39; System.InvalidOperationException&#39;发生在System.Xml.dll那里   是反映类型&#39; Program.Root&#39;的错误。无法序列化对象   类型&#39; Program.Root&#39;。考虑更改XmlText成员的类型   &#39; Program.Root.Bytes&#39;从System.Byte []到字符串或字符串数​​组。

但我需要让我的Bytes数组包含文件二进制,因为使用MTOM,如果长度小于768字节,它将由base64中的 CreateMtomWriter 序列化或 xop:Include ,如果超过768个字节。

我希望它被编码为Root Element的直接子元素,而不是包含在任何其他元素中。

如果在Root类中,我只放置了Bytes或List属性,它可以完美地工作,但是如果我把两者都放在一起,那就没有了。

2 个答案:

答案 0 :(得分:1)

您似乎遇到了XmlSerializer错误。

如果我将类更改为删除 List属性,请执行以下操作:

public class Root
{
    [XmlText]
    public byte[] Bytes { get; set; }
}

然后XmlSerializer将成功序列化,字节数组自动表示为基本64字符串:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">AAECAwQFBgcICQ==</Root>

相反,如果我更改类以使XmlText属性成为string值的代理属性,将字节数组转换为基数64,那么XmlSerializer将< em>再次成功序列化且相同

public class Root
{
    [XmlIgnore]
    public byte[] Bytes { get; set; }

    [XmlText]
    public string Base64Bytes
    {
        get
        {
            return Bytes == null ? null : Convert.ToBase64String(Bytes);
        }
        set
        {
            Bytes = value == null ? null : Convert.FromBase64String(value);
        }
    }

    [XmlElement]
    public List<string> List { get; set; }
}

实际上,XmlTextAttribute.DataType的文档清楚地表明字节数组是[XmlText]支持的数据类型之一。 Neverthess,[XmlText] byte [] Byte { get; set; }属性与同一类中任何其他[XmlElement]属性的组合导致XmlSerializer构造函数抛出异常。您可能希望report a problem to Microsoft,因为没有理由不这样做。

与此同时,您可以使用字符串值代理属性的变通方法,如上所示。

答案 1 :(得分:0)

来自微软: 感谢您报告此问题。这是设计的。字节数组不能是文本值。请尝试解决此问题,例如使用字符串。