是否有办法使用Json.Net来反序列化一些json,这些json调用一个方法来将项目添加到集合中(没有属性setter



我有一个类,它有一个集合是readonly,没有setter。

是否有一种方法来反序列化一些json,并让它调用实例上的方法,而不是属性setter?

例如:

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 json中有一个数组的电影,它将调用AddMovieAddMovies

忍者更新由PK:
根据下面的答案,我使用类的集合而不是简单的字符串来分叉下面的代码,以获得一个现在可以工作的更复杂的示例。


使用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;

Here's fiddle

相关内容

  • 没有找到相关文章