XmlSerializer 错误、字节数组、列表和 InvalidOperationException
XmlSerializer Error, bytes array, List and InvalidOperationException
我发现 C# 中的 XmlSerializer 有一个奇怪的行为,有人帮助我吗?
我想要 SOAP/MTOM 中的这个 XML,并且我需要任何其他 XML 元素之外的 xop:Include:
<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' occurred in System.Xml.dll There
was an error reflecting type 'Program.Root'. Cannot serialize object
of type 'Program.Root'. Consider changing type of XmlText member
'Program.Root.Bytes' from System.Byte[] to string or string array.
但我需要让我的字节数组包含 二进制文件,因为使用 MTOM,它将由 CreateMtomWriter 在 base64 中序列化如果长度小于 768 字节或 xop:Include 如果大于 768 字节。
我希望它被编码为根元素的直接子元素,而不是包含在任何其他元素中。
如果在 class 根目录中,我只放入字节或列表 属性,它会完美地工作,但如果我同时放入两者,则不会。
您似乎遇到了 XmlSerializer
错误。
如果我将 class 更改为 删除 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>
相反,如果我更改 class 以使 XmlText
属性 成为转换字节数组的 string
值代理 属性从和到 base 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
clearly indicates that byte arrays are one of the data types supported by [XmlText]
. Neverthess, the combination of an [XmlText] byte [] Byte { get; set; }
property with any other [XmlElement]
property in the same class causes the XmlSerializer
constructor to throw an exception. You might want to report a problem to Microsoft 的文档,因为没有理由不工作。
同时,您可以使用字符串值代理 属性 的解决方法,如上所示。
来自微软:
感谢您报告此问题。这是设计使然。字节数组不能是文本值。请尝试解决此问题,例如使用字符串。
我发现 C# 中的 XmlSerializer 有一个奇怪的行为,有人帮助我吗? 我想要 SOAP/MTOM 中的这个 XML,并且我需要任何其他 XML 元素之外的 xop:Include:
<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' occurred in System.Xml.dll There was an error reflecting type 'Program.Root'. Cannot serialize object of type 'Program.Root'. Consider changing type of XmlText member 'Program.Root.Bytes' from System.Byte[] to string or string array.
但我需要让我的字节数组包含 二进制文件,因为使用 MTOM,它将由 CreateMtomWriter 在 base64 中序列化如果长度小于 768 字节或 xop:Include 如果大于 768 字节。
我希望它被编码为根元素的直接子元素,而不是包含在任何其他元素中。
如果在 class 根目录中,我只放入字节或列表 属性,它会完美地工作,但如果我同时放入两者,则不会。
您似乎遇到了 XmlSerializer
错误。
如果我将 class 更改为 删除 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>
相反,如果我更改 class 以使 XmlText
属性 成为转换字节数组的 string
值代理 属性从和到 base 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
clearly indicates that byte arrays are one of the data types supported by [XmlText]
. Neverthess, the combination of an [XmlText] byte [] Byte { get; set; }
property with any other [XmlElement]
property in the same class causes the XmlSerializer
constructor to throw an exception. You might want to report a problem to Microsoft 的文档,因为没有理由不工作。
同时,您可以使用字符串值代理 属性 的解决方法,如上所示。
来自微软: 感谢您报告此问题。这是设计使然。字节数组不能是文本值。请尝试解决此问题,例如使用字符串。