【问题标题】:Why does CanDeserialize always return false when deserialization succeeds?为什么反序列化成功后CanDeserialize总是返回false?
【发布时间】:2022-11-20 07:18:42
【问题描述】:

我试图将一个 xml 字符串反序列化为一个对象,这没什么奇怪的。在我将我的项目升级到 .Net5 之前,一切都很好。

在升级中,我必须添加对包 Microsoft.XmlSerializer.Generator 的引用,并更改项目文件以添加以下内容:

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="1.0.0" />
</ItemGroup>

这使我能够创建 XmlSerializer(第一个错误很奇怪)。但是,现在,如果该类具有 XmlRoot 属性,则每次对 XmlReader 上的 CanDeserialize 调用都会返回 false。现在,我可以反序列化 xml 文本。那确实有效。但是为什么 CanDeserialize 会基于这种情况而失败呢?

下面是我用来在控​​制台应用程序 (.Net5) 中测试的类和代码。

[Serializable, XmlRoot("TestObj")]
//[Serializable]
public class TestObj
{
    public int TestVal;
}

static void Main(string[] args)
{
    var serializer = new XmlSerializer(typeof(TestObj));

    //generated by doing a test serialization of the class
    var teststr = "<TestObj xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><TestVal>2</TestVal></TestObj>";

    using (var str = new StringReader(teststr))
    using (var reader = XmlReader.Create(str))
    {
        if (serializer.CanDeserialize(reader))
            Console.WriteLine(((TestObj)serializer.Deserialize(reader)).TestVal);
        else
        {
            Console.WriteLine("Value cannot be deserialized into the given Type");
            //try it anyway
            var o = (TestObj)serializer.Deserialize(reader);
            Console.WriteLine(o.TestVal);
        }
    }
}

我的解决方法只是消除 CanDeserialize 调用并将反序列化包装在 try..catch 中,但我仍然很好奇为什么会这样。

【问题讨论】:

  • 嗯,无法使用 .NET 6 小提琴重现,请参阅dotnetfiddle.net/DwbPuZ。为什么需要添加对Microsoft.XmlSerializer.Generator 的引用?您实际上是否在构建时使用它为您的类型创建 XML 序列化程序集?
  • 另外,如果你在调用CanDeserialize之前调用XmlReader.MoveToContent()会发生什么?
  • 我必须测试 MoveToContent() 调用。我以前从来没有这样做过。由于我提到的奇怪错误,我不得不添加参考。创建 XmlSerializer 会失败。错误消息说找不到 {MyProject}.XmlSerializer.dll。是的,它认为 XmlSerializer 在我的项目命名空间中。哪怕我特地声明过。没有构建错误。我清理并重新启动了一切。 Generator 包是我能找到的唯一修复程序。
  • 关于奇怪的错误, new XmlSerializer() 构造函数实际上失败?它在内部尝试在磁盘上查找已保存的序列化 DLL。如果不存在,则存在内部异常,但它会在构造函数中被捕获并吞噬,因此是无害的。参见XmlSerializer giving FileNotFoundException at constructor。您是否有机会在调试器或日志文件中看到第一次异常并认为这是问题所在,但实际问题完全不同?
  • 是的,新的构造函数失败了。该错误具体是在 XmlSerializer 上引用项目的命名空间。但是,您对此的质疑确实给了我一个尝试的想法,我现在将其作为答案发布。

标签: xml-serialization .net-5 xmlserializer


【解决方案1】:

好吧,关于@dbc 问题的 cmets 确实让我尝试了别的东西。我在原始问题中留下的一些细节因为它似乎不相关(由于涉及测试)是我在非测试中尝试反序列化的类在 .Net Standard 2.1 库中。而进行反序列化的项目是.Net5。

最终,我得到了这份工作。我不得不在基于 .Net Standard 的库中引用 Microsoft.XmlSerializer.Generator 包,但在 .Net5 项目中没有引用它。

简而言之,将包引用从标准项目中移除会导致一个错误,而将其包含在两者中会导致另一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多