c# - XML 文档 (1, 1) 中存在错误。反序列化一个简单的 xml 字符串时

标签 c# xml

我检查了this post之前,但它对我没有帮助(它也没有被接受的答案)。

这个测试失败了:

using System.IO;
using System.Xml.Serialization;
using Xunit;

namespace ATest
{
    public class XmlSerializerTest
    {
        [Fact]
        public void DeserializeTest()
        {
            string request = Serializer.ByteArrayToString(new RegisterRequest{ ... }
               .ToXml());

            RegisterRequest deserialized = request.DeserializeXmlString<RegisterRequest>();

            Assert.NotNull(deserialized);
        }
    }

    public static class Serializer
    {
        public static T DeserializeXmlString<T>(this string xmlObj)
        {
            T outputObject;
            using (StringReader xmlReader = new StringReader(xmlObj))
            {
                var serializer = new XmlSerializer(typeof(T));
                outputObject = (T)serializer.Deserialize(xmlReader); // throws here
            }
            return outputObject;
        }

        public static byte[] ToXml<T>(this T obj)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            settings.Indent = false;

            using MemoryStream ms = new MemoryStream();
            using XmlWriter xmlWriter = XmlWriter.Create(ms, settings);

            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(String.Empty, String.Empty);

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(xmlWriter, obj, namespaces);

            return ms.ToArray();
        }

        // And convert that byte[] to string with this:
        public static string ByteArrayToString(byte[] bytes) =>
                Encoding.UTF8.GetString(bytes);
    }

    [XmlRoot(elementName: "RegisterRequest")]
    public class RegisterRequest
    {
        [XmlElement]
        public int WorkerId;

        [XmlElement]
        public string WorkerIP;

        [XmlElement]
        public int WorkerPort;
    }
}

我得到的错误是:

System.InvalidOperationException: 'There is an error in XML document (1, 1).'

InnerException XmlException: Data at the root level is invalid. Line 1, position 1.

最佳答案

这里的问题是 Encoding.UTF8 是带有 BOM(字节顺序标记)的 UTF-8 编码,这意味着 XmlSerializer 在开头发出几个字节以指示所述字节顺序标记。因此,您的 ToXml 的结果在开头包含那些非字符字节,并且反序列化失败,因为反序列化不需要它们。要修复,请通过执行以下操作告诉序列化程序不要发出 BOM:

XmlWriterSettings settings = new XmlWriterSettings();
//settings.Encoding = Encoding.UTF8;
settings.Encoding = new UTF8Encoding(false); // false means no BOM here

顺便说一句,您粘贴到问题中的文本不包含所述不可见字符,因此使用您粘贴的特定硬编码字符串无法重现问题。但是,由于您包含了产生问题字符串的代码 - 可以通过手动调用 ByteArrayToString(ToXml(..)) 来重现它。

关于c# - XML 文档 (1, 1) 中存在错误。反序列化一个简单的 xml 字符串时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64480712/

相关文章:

python - 当我传递特定参数时,使用 ElementTree 的 iter() 解析 XML 没有找到我的标签

c# - 在文本框控件中添加标签

c# - Greybox GB_showcenter 不显示弹出窗口

c# - 跟踪已完成/正在运行的 System.Threading.Tasks.Task 对象

c# - 使用 FromQuery 时是否可以将类对象默认为 null

xml - R:读取连接 XML 数据实例 (ODK)

java - 在转换为 Java 对象之前检查 xsd datetime 是否有定义的时区

java - 将 XML 文件作为资源加载

java - 在小部件android上绘制 Canvas

c# - 无需自动化即可读取(和写入)Office 文档自定义属性