将转换器应用于Json Array中的所有元素

时间:2014-02-15 20:23:06

标签: c# json.net

可以通过定义这样的类来使用自定义转换器:

public class MyCustomConverter : JsonConverter
{

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

    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 ret = new MyCustomType();
        return ret;
    }
}

然后像这样使用它:

MyCustomType item = JsonConvert.DeserializeObject<MyCustomType>(jsonString, new MyCustomTypeConverter());

我的问题是,在处理MyCustomType列表时如何应用此反序列化程序?基本上我有一个Json数组([{ ... }, { ... }]),我想在数组的每个项目上使用上面的转换器来获得List<MyCustomType>

我知道我可以使用JArray对象及其方法手动完成,但我想知道是否有更简单,更清晰的方法。


这是一个简化的背景。

C#(我想反序列化List的那些):

class MyCustomType
{
    public Dictionary<string, string> Data
    {
        get;
        set;
    }
    public int Id
    {
        get;
        set;
    }
}

JSON(数组示例中的一项):

{
    "Id": 50,
    "Data": [
        "Hello",
        "World"
    ]
}

C#反序列化我想申请:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var ret = new MyCustomType();
    ret.Data = new Dictionary<string, string>();
    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.EndObject)
        {
            continue;
        }

        var value = reader.Value.ToString();
        switch(value)
        {
            case "Id":
                ret.Id = reader.ReadAsInt32().Value;
                break;
            case "Data":
                ret.Data.Add(MySingleton.Instance.CurrentLanguage, reader.ReadAsString());
                break;
        }
    }
    return ret;
}

2 个答案:

答案 0 :(得分:2)

var obj = JsonConvert.DeserializeObject<MyCustomType>(json);

如果你的json是一个数组,那么使用

var obj = JsonConvert.DeserializeObject<List<MyCustomType>>(json);

如果您可以将Data的类型更改为List<string>,则甚至不需要 jsonConverter


public class MyCustomType
{
    public int Id { get; set; }
    [JsonConverter(typeof(MyCustomConverter))]
    public Dictionary<string, string> Data { get; set; }
}

public class MyCustomConverter : JsonConverter
{

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

    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)
    {
        // read the string array and convert it to dictionary 
        // as declared in your MyCustomType
        var arr = serializer.Deserialize<List<string>>(reader);
        return arr.ToDictionary(x => x, x => x);
    }
}

修改

只需反序列化为

var yourObj = JsonConvert.DeserializeObject<MyCustomType.Rootobject>(yourjson);

public class MyCustomType
{

    public class Rootobject
    {
        public Datum[] data { get; set; }
    }

    public class Datum
    {
        public string id { get; set; }
        public string al { get; set; }
        public string[] datapsi { get; set; }
        public string[] tags { get; set; }
        public string partype { get; set; }
        public Info info { get; set; }
        public Factors factors { get; set; }
        public Espace[] espace { get; set; }
        public Annex Annex { get; set; }
    }

    public class Info
    {
        public string nopub { get; set; }
        public int nodem { get; set; }
    }

    public class Factors
    {
        public int a { get; set; }
        public float b { get; set; }
        public int c { get; set; }
        public float d { get; set; }
        public int e { get; set; }
        public float f { get; set; }
        public float g { get; set; }
        public int h { get; set; }
        public int i { get; set; }
        public int j { get; set; }
        public int k { get; set; }
        public int l { get; set; }
        public float m { get; set; }
        public int n { get; set; }
        public int o { get; set; }
        public int p { get; set; }
        public float q { get; set; }
        public float r { get; set; }
        public int s { get; set; }
        public float t { get; set; }
    }

    public class Annex
    {
        public string name { get; set; }
        public Image image { get; set; }
    }

    public class Espace
    {
        public string id { get; set; }
        public string description { get; set; }
        public Datatip datatip { get; set; }
        public Image image { get; set; }
        public string resource { get; set; }
        public int delta { get; set; }
        public int[] target { get; set; }
        public string targetType { get; set; }
        public string targetOneLined { get; set; }
        public int[] alx { get; set; }
        public string alxOneLined { get; set; }
        public int[][] damps { get; set; }
        public string[] dampsOneLined { get; set; }
        public Var[] vars { get; set; }
        public object misc { get; set; }
        public string miscOneLined { get; set; }
    }

    public class Datatip
    {
        public string[] label { get; set; }
        public string[] damps { get; set; }
    }

    public class Image
    {
        public string full { get; set; }
        public string sprite { get; set; }
        public string group { get; set; }
        public int x { get; set; }
        public int y { get; set; }
        public int w { get; set; }
        public int h { get; set; }
    }

    public class Var
    {
        public string key { get; set; }
        public string link { get; set; }
        public float coeff { get; set; }
    }
}

答案 1 :(得分:-1)

虽然L.B's answer有效,但有些情况下确实需要转换器 - 例如,当您没有触及原始JSON并且只能获得将要使用的ASP.NET方法时可以访问HTTP请求。

在这种情况下,您可以使用JsonPropertyAttribute class并为其ItemConverterType property分配一个值:

[JsonProperty(ItemConverterType = typeof(MyCustomConverter))]
public List<MyCustomType> Items { get; set; }