C# 将转换器应用于Json数组中的所有元素

C# 将转换器应用于Json数组中的所有元素,c#,json.net,C#,Json.net,可以通过定义如下类来使用自定义转换器: public class MyCustomConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(MyCustomType); } public override void WriteJson(JsonWriter writer, object va

可以通过定义如下类来使用自定义转换器:

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());
然后像这样使用它:

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());
JSON(数组示例中的一项):

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;
}
public override object ReadJson(JsonReader reader,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var ret=新的MyCustomType();
ret.Data=新字典();
while(reader.Read())
{
if(reader.TokenType==JsonToken.EndObject)
{
继续;
}
var value=reader.value.ToString();
开关(值)
{
案例“Id”:
ret.Id=reader.ReadAsInt32().Value;
打破
案例“数据”:
Add(MySingleton.Instance.CurrentLanguage,reader.ReadAsString());
打破
}
}
返回ret;
}

虽然可以工作,但在某些情况下确实需要转换器——例如,当您无法接触原始JSON,而只能访问HTTP请求可以访问的属性ASP.NET方法时

在这种情况下,可以使用并为其指定一个值:

[JsonProperty(ItemConverterType=typeof(MyCustomConverter))]
公共列表项{get;set;}

发布一个真正的json,并解释您想要从中得到什么(比如MycustomType是如何定义的)。在文章中添加了一个简化的上下文。谢谢您的回答,但是我如何处理
Id
属性?这是一个简化的上下文,
MyCustomType
实际上是一个更复杂的对象,它有自己的子对象,需要转换为well@RedPolygon事实上,我认为您的案例中不需要JsonConverter。即使你有一个复杂的对象。只需发布真正的json,我们就可以发布一个有效的答案。这里是一个原始json:。我添加了一些注释(使用
/
),尽管我知道注释不是
JSON
的一部分。我没有对所有需要转换为
字典的行进行注释,但您会明白:)问题是,存在大量类型不匹配。例如,
Datum.datapsi
的类型是
Dictionary
,而不是
string[]
(即使在Json中它是
string
的数组)。我无法控制模型,因此我需要一个转换器(它们的
字典
键不是
Json
的一部分,并且来自独立的源代码)。谢谢你花时间来帮助我:)@RedPolygon
例如,Datum.datapsi是字典类型,而不是string[]
我想我在回答的第一部分解释了你如何做到这一点。不确定你为什么投了反对票?这是最简单的、本机支持的答案。不幸的是,可怜的Json.Net文档将这样的信息存储在搜索引擎上从未出现过的页面上。
var obj = JsonConvert.DeserializeObject<MyCustomType>(json);
var obj = JsonConvert.DeserializeObject<List<MyCustomType>>(json);
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; }
    }
}
[JsonProperty(ItemConverterType = typeof(MyCustomConverter))]
public List<MyCustomType> Items { get; set; }