【问题标题】:.NET NewtonSoft JSON deserialize list with auto-increment index.NET NewtonSoft JSON 反序列化具有自动递增索引的列表
【发布时间】:2018-07-07 06:04:42
【问题描述】:

我现在的情况是我有一个json文件

[
    {
        "first_name" : "Foo",
        "last_name" : "Bar",
        "gender" : 0
    },
    {
        "first_name" : "FooFoo",
        "last_name" : "BarBar",
        "gender" : 1
    }
]

还有一个 Person 类:

class Person
{
    public Id { get; private set; }
    public string FirstName;
    public string LastName;
    public int Gender; 
}

我正在使用这样的反序列化器:

JArray.ToObject<List<Person>>();

或等价物:

JsonConvert.DeserializeObject<List<Person>>(jsonstr, ...)

虽然json对象本身没有,但在Person类中有一个“Id”字段,我需要它根据Person在列表中的位置增加值。

我不能将 Id 设为公共属性并在反序列化后设置它的原因是,它是一个 Id,它不应该是可编辑的,而且我认为编程不好。

我听说过 JsonConverters。使用它们可以实现吗?我需要一些帮助。总结一下,我需要一种将 Json 数组反序列化为对象列表并自动将它们设置为自动递增 Id 的方法。

那么,谢谢您的宝贵时间。

【问题讨论】:

  • 您的 ID 访问修饰符设置为私有,因此序列化方法最受访问修饰符级别的影响
  • 有很多解决方案,但我认为你可以有一个公共访问修饰符的属性,然后在 seter 方法中可以做你想做的事
  • @AliSheikhNezami 将 OP 私有字段更改为具有私有设置器的公共字段...但这不是问题...问题仍然存在。我可以在反序列化后手动设置 ID,并且在设置后(又名... Id!= null)无法再设置 Id。不知道这样的做法会有多好。

标签: c# json.net json-deserialization


【解决方案1】:

你不需要在反序列化过程中改变任何东西,你可以简单地在类的构造函数中做一些事情:

static int NextId = 0;

public Person() 
{
     Id = NextId++;
}

而且,是的,您绝对不希望您的 ID 可编辑。这里的一个好的模式是

public int Id { get; private set;}

您还可以在 Id 上放置 [JsonIgnore] 属性。这意味着不会将其分配给。

[JsonIgnore]
public int Id { get; private set;}

重置 ID

public static void ResetNextId(int startId)
{
    NextId = startId;
}

Person.ResetNextId(0);

还有一个 [OnDeserialized] 属性,您可以将其应用于对象上的过程,以在对象被反序列化后分配属性。

[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
     // Do stuff
}

【讨论】:

  • 问题是我希望 Id 相对于它在 List 上的位置而不是全局 Id,所以会有很多 List 并且每个项目的第一项的 Id将是 0。
  • 啊,是的,当然你可以添加一个静态的 ResetId 过程来做到这一点。
  • 嗯.. 这将是一个有趣的选择!我什至可以使用包装器方法来反序列化最终会调用该过程的列表。
  • 好主意!如果你想避免重置调用,你也可以使用 Guids!
  • 我可以将 OnDeserialized 应用到 List 而不是单个对象吗?!
猜你喜欢
  • 1970-01-01
  • 2019-12-20
  • 2013-06-06
  • 1970-01-01
  • 2020-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多