【问题标题】:XmlSerializer Error, bytes array, List and InvalidOperationExceptionXmlSerializer 错误、字节数组、列表和 InvalidOperationException
【发布时间】:2016-05-29 16:20:40
【问题描述】:

我在 C# 中发现 XmlSerializer 有一个奇怪的行为,有人帮助我吗? 我想要 SOAP/MTOM 中的这个 XML,并且我需要 xop:Include 在任何其他 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; }
}

我的错误是:

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

但我需要让我的 Bytes 数组包含 file binary 因为使用 MTOM,如果长度小于 768 字节,它将由 CreateMtomWriter in base64 序列化如果超过 768 字节,则在 xop:Include 中。

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

如果在 Root 类中,我只放了 Bytes 或 List 属性,它工作得很好,但如果我把两者都放了,那就不行了。

【问题讨论】:

  • 您的预期输出是什么?您希望在哪里对该字节数组进行编码?

标签: c# xml xmlserializer mtom


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您似乎遇到了XmlSerializer 错误。

    如果我将类更改为 删除 List 属性,如下所示:

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

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

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

    相反,如果我更改类以使 XmlText 属性成为 string-valued 代理属性,它将字节数组从基数 64 转换为基数,然后 XmlSerializer 将再次 > 成功序列化它并且完全相同

    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] 支持的数据类型之一。尽管如此,[XmlText] byte [] Byte { get; set; } 属性与同一类中的任何其他 [XmlElement] 属性的组合会导致 XmlSerializer 构造函数引发异常。您可能想report a problem to Microsoft,因为没有理由不这样做。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多