有没有一种方法可以使用Json.net来反序列化一些调用方法将项添加到集合中的JSON(没有属性设置器)

nx7onnlm  于 2023-01-06  发布在  .NET
关注(0)|答案(1)|浏览(113)

我有一个类,它有一个集合readonly,没有setter。
有没有一种方法可以反序列化一些json,并让它调用示例上的方法而不是属性设置器?
例如:

public class User
{
    private ObservableCollection<Movie> _movies;
    public string Name { get; set; }
    public ReadOnlyCollection<Movie> FavouriteMovies { get; set; }
    public void AddMovie(Movie movie) { .. }
    //-or-
    public void AddMovies(IEnumerable<Movie> movies){ .. }
}

将内容放入_movies后备字段的唯一方法是通过方法AddMovies。因此,当尝试反序列化某个在json中包含Movies数组的有效json时,它将调用AddMovieAddMovies ...

liwlm1x9

liwlm1x91#

Ninja按PK更新:

我已经使用了一个 * 类 * 的集合而不是简单的字符串forked the fiddle below,对于一个更复杂的例子,现在工作,基于下面的答案。
使用一个JsonConverter来定制你的json的转换。这里有一个简单的例子来说明它是如何工作的。给定一个这样的类:

public class MyClass
{
    private List<string> backingField;

    public string Name { get; set; }
    public IReadOnlyCollection<string> MyStrings { get; private set; }

    public MyClass()
    {
        backingField = new List<string>();
        MyStrings = backingField.AsReadOnly();
    }

    public void AddString(string item)
    {
        backingField.Add(item);
    }
}

JSON是这样的:

{
    "MyStrings": [
        "Foo",
        "Bar"
    ],
    "Name":"My stuff"
}

您可以创建一个转换器来读取该json并调用AddString来填充backingField,如下所示:

public class MyClassConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var obj = new MyClass();    
        var jObj = JObject.Load(reader);
        JsonConvert.PopulateObject(jObj.ToString(), obj);           // populate fields we don't need any special handling for
        var stringsProp = jObj["MyStrings"];
        if (stringsProp != null)
        {
            var strings = stringsProp.ToObject<List<string>>();
            foreach (var s in strings)
            {
                obj.AddString(s);
            }
        }
        return obj;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MyClass);
    }
}

现在要使用它,并使MyClass不知道它是如何反序列化的,只需执行以下操作:

var m = JsonConvert.DeserializeObject(json, typeof(MyClass), new MyClassConverter()) as MyClass;

这是一个fiddle

相关问题