gpt4 book ai didi

c# - Newtonsoft JSON.NET 反序列化错误

转载 作者:太空狗 更新时间:2023-10-29 22:37:00 26 4
gpt4 key购买 nike

我在单个文件中有一堆长 json 输出。我需要读取这些文件并将它们反序列化为最初生成 json 的实体(我可以访问原始实体)。每个文件都有通过序列化 IEnumerable<Response<MyEntity>> 类型的对象生成的 json 输出。 .

我在尝试反序列化时遇到异常,但我不明白为什么。这是我反序列化的尝试:

List<string> jsonOutputStrings;
// Read json from files and populate jsonOutputStrings list
List<Response<MyEntity>> apiResponses = new List<Response<MyEntity>>();

foreach (string json in jsonOutputStrings)
{
apiResponses.AddRange(JsonConvert.DeserializeObject<List<Response<MyEntity>>>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }).ToList());
}

我还尝试反序列化为 IEnumerable 而不是列表:

apiResponses.AddRange(JsonConvert.DeserializeObject<IEnumerable<Response<MyEntity>>>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }).ToList());

我得到以下异常:

A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Cannot create and populate list type System.Linq.Enumerable+WhereSelectListIterator`2[Entities.Requirement,Entities.RequirementEntity]. Path '$values[0].ReturnedEntity.Summaries.$values[0].Requirements.$values', line 1, position 715.

整个 json 太长而无法发布(并且还包含一些 secret 数据)但我确实在 json 中找到了一个包含以下内容的位置:

"Requirements":{"$id":"7","$type":"System.Linq.Enumerable+WhereSelectListIterator`2[[Entities.Requirement, Entities],[Entities.RequirementEntity, API.Entities]], System.Core","$values":[...]}

在我尝试反序列化的实体中(与最初序列化的实体相同),Requirements类型为 IEnumerable<Entities.RequirementEntity> .

如何从 MyEntity 序列化对我来说没有意义有效,但反序列化为相同类型则无效。我该如何解决这个问题?

最佳答案

您必须浏览 Response<>MyEntity并查看集合是如何初始化的。这告诉我们某个类中的一个集合是使用 Where 创建的来自linq的方法。您可以通过执行以下代码重现此错误:

class MyEntity
{
public MyEntity()
{
Data = new List<string>().Where(x => true);
}

public IEnumerable<string> Data { get; set; }

}

class Program
{
static void Main(string[] args)
{
string data = @"[{""Data"":[""a"",""b""]}]";
var j = JsonConvert.DeserializeObject<IEnumerable<MyEntity>>(data);
}
}

另一种可能性是在 json 中包含元数据。那么你有 2 个解决方案:

  • 设置TypeNameHandlingTypeNameHandling.None (正如评论中提到的那样);
  • 用有效的类型替换字符串中无效的类型

使用 TypeNameHandling.None当你有 IEnumerable<BaseType> 时,可能会导致 exmaple 的反序列化错误该列表包含 BaseType 的子类型.

在这种情况下,您应该选择第二个选项。基本上,您应该替换任何未反序列化的类型,并将其替换为例如 List .

示例代码:

class MyEntity
{
public IEnumerable<string> Data { get; set; }
}

class Program
{
static void Main(string[] args)
{
IList<MyEntity> entities = new MyEntity[] {
new MyEntity { Data = new [] { "1", "2" }.Where(x => x != string.Empty) },
new MyEntity { Data = new [] { "A", "B" }.AsQueryable().Where(x => x != string.Empty) },
new MyEntity { Data = new List<string> { "A", "B" } },
};

string data = JsonConvert.SerializeObject(entities, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
data = Regex.Replace(data, "\"\\$type\":\\s+\"System.Linq.Enumerable\\+WhereArrayIterator(.+?), System.Core\",", "\"$type\": \"System.Collections.Generic.List$1, mscorlib\",", RegexOptions.Singleline);

var j = JsonConvert.DeserializeObject<IEnumerable<MyEntity>>(data, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
}
}

关于c# - Newtonsoft JSON.NET 反序列化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27534786/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com