【问题标题】:How to get object json when deserializing array反序列化数组时如何获取对象json
【发布时间】:2015-06-06 05:32:49
【问题描述】:

我有一个传入的 JSON,其中包含一些对象的数组,例如 Foo。我用

反序列化它们
result = JsonConvert.DeserializeObject<List<Foo>>(message);

现在我想向 Foo 添加一个字符串属性,它将存储它的 JSON(我收到),所以 Foo 看起来像:

    public class Foo
{
    public int MyInt { get; set; }
    public bool MyBool { get; set; }
    public string JSON { get; set; }
}

但我不知道 JSON.Net 可以填充这样一个字段的方式..

UPD 我会澄清我想要的。假设我收到 JSON:

[{"MyInt":1,"MyBool":0},{"MyInt":2,"MyBool":0},{"MyInt":3,"MyBool":1}]

这里是 3 个对象的数组,我想在反序列化时将 json 的相应部分添加到对象中,这样:

第一个对象将包含{"MyInt":1,"MyBool":0}

第二个对象将包含{"MyInt":2,"MyBool":0}

第三个对象将包含{"MyInt":3,"MyBool":1}

在他们的JSON 属性中

如有任何帮助,我将不胜感激!

【问题讨论】:

  • 当您反序列化为 Foo 的列表时,您是否想要 Foo 的每个实例中的完整 JSON 文本的副本?您是否打算再次将 Foo 列表连载?
  • @Ulric 不,我想将 json 的对象部分添加到它的字段中。请参阅我的帖子编辑以获取说明

标签: c# json serialization json.net


【解决方案1】:

这是一种方法,但它不保持确切的原始 JSON - 但它确实提供了原始 JSON 的静态记录(但没有原始值的确切格式 - 即 Bool 可能是 0/ 1 或真/假):

var message = @"[{""MyInt"":1,""MyBool"":0},{""MyInt"":2,""MyBool"":0},{""MyInt"":3,""MyBool"":1}]";
var foos = JsonConvert.DeserializeObject<List<Foo>>(message);
var t = JsonConvert.SerializeObject(foos[0]);
foos = foos.Select(s => new Foo() { MyBool = s.MyBool, MyInt = s.MyInt, JSON = JsonConvert.SerializeObject(s) }).ToList();

如果您正在处理大量的 Foo,那么您可能希望找到一种更有效的方法。可能有一种方法可以使用 linq 进行“更新”,而不是创建新列表。

【讨论】:

  • Brian 提出了类似的解决方案,我需要的正是原始 JSON,而不是重新序列化的 JSON
  • 它将技术上存储原始 JSON。如果 JSON 有问题,它不会反序列化 - 但如果没有问题,重新序列化的值将(出于所有意图和目的)匹配。 (Brian 建议的问题是更改属性会更改 JSON。)但如果这还不够“准确”,那么 NP :)
  • @Ulric 它没有。见Fiddle。请注意,原始中的布尔值是 10,但在输出中是 truefalse。另请注意,输出中包含 JSON 成员,而原始成员没有。
  • @Brian 啊是的 - 你是对的。我以前没有注意到这一点。 >归档以备将来参考
  • @Ulric 好吧,我的问题仍然是我可以收到一个非常大的 JSON(我真的可以而且很多次),在一个项目上失败,丢失其他项目(在反序列化失败期间)然后我'将不得不记录整个 JSON...我可以以某种方式将初始数组“拆分”为项目,然后逐个解析它们吗?
【解决方案2】:

好的,我找到了答案。我不知道我可以将消息反序列化为 JArray 然后枚举它(干得好,newtonsoft :))。这是我最终得到的结果:

if (tokenType is JArray)
                {
                    var arr = JsonConvert.DeserializeObject(message) as JArray;
                    foreach (var item in arr)
                    {
                        try
                        {
                            var agentParameter = item.ToObject<Foo>();
                            agentParameter.JSON = item.ToString();
                            result.Add(agentParameter);
                        }
                        catch (Exception)
                        {
                            LogProvider.Error(string.Format("Failed to Deserialize message. Message text: \r\n {0}", item.ToString()));
                        }
                    }
                }

【讨论】:

  • item.ToString() 也会重新序列化对象。它不返回原始 JSON。
  • @BrianRogers 太可惜了,你说得对:(我可以从 JToken 中提取原始 JSON 吗?
  • 我不这么认为——只是在调查,但似乎 Json.Net 在解析时并没有挂在原始 JSON 上。一旦它被转换成一个值(或 JToken),原始的就会被丢弃。您可能需要寻找不同的解析器。
  • @BrianRogers Brian,我测试了我的解决方案,当我将一些不正确的值粘贴到数组中的 json 项中时,ToObject 抛出异常,并且 ToString 返回原始 JSON。所以我用try-catch把它包起来,现在我有了我想要的。非常感谢您的帮助!
  • 没问题;很高兴您能够找到适合您的解决方案。
猜你喜欢
  • 2021-05-30
  • 1970-01-01
  • 2015-06-11
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多