使用ImmutableList(仅限发布模式)在UWP上使用JSON.NET反序列化问题

本文关键字:JSON NET 问题 反序列化 UWP 布模式 使用 模式 ImmutableList | 更新日期: 2023-09-27 18:27:42

我遇到了一种烦人而奇怪的行为,它在调试和发布模式之间有所不同。因此,我们使用的是UWP 10.0.10586,使用的是JSON.NET 7.0.1

我有一个模型类,看起来像这样:

[JsonObject]
public class RootObject
{
    [JsonProperty]
    public Profile ProfileInfo { get; set; } = new Profile();
    [JsonProperty]
    public ImmutableList<Info> AdditionalInfo { get; set; } = ImmutableList.Create<Info>();
}

然后我尝试反序列化json:

var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

这在调试模式下非常有效,但在发布模式下不会反序列化AdditionalInfo(列表为null)。

如果我使用IEnumerable或IList而不是ImmutableList,它也会起作用,但我想知道这种行为是否有原因,或者可能是JSON.NET错误。

使用ImmutableList(仅限发布模式)在UWP上使用JSON.NET反序列化问题

很可能您遇到了.NET Native的运行时异常之一。要正确诊断此问题,我建议为项目的DEBUG配置启用.NET Native编译(项目属性>BUILD>启用.NET Native复选框)。然后,将调试器设置为在第一次出现异常时停止。

现在,当你运行时,你可能会看到一个MissingMetadataException或一些关于序列化的消息,但因为你在调试中,你会得到不错的异常字符串。如果您可以转到更新1,则消息会更好一些。很可能您需要在Default.rd.xml文件中添加一些内容。

为了反射激活ImmutableCollection<T>,Json.NET反映了ImmutableCollection试图查找CreateRange方法。由于使用了非平凡反射,.NET Native编译器无法预测这一点,因此此查找失败。来自Json.NET的错误消息非常不幸,因为它没有告诉您无法反射查找ImmutableCollection.CreateRange才是真正的问题。

既然我们知道这是问题所在,我们可以在http://dotnet.github.io/native/troubleshooter/type.html构造一段RD.XML来修复它。修复它的RD.XML是:

<Type Name="System.Collections.Immutable.ImmutableList" Dynamic="Required All" />

我们也遇到了类似的问题,但.rd.xml技巧并没有解决它。该代码将JSON反序列化为动态对象,在调试模式下运行良好,在将UWP更新为10.0.15138之前,在发布模式下运行。但现在它在发布模式下崩溃了。

这是修复之前的行(不起作用):

dynamic obj = JsonConvert.DeserializeObject(rpcStatus);

修复方法是将ExpandoObject指定为Newtonsoft反序列化的类型,如下所示(确实有效):

dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(rpcStatus);