我陷入了糟糕的API,该API返回以下JSON:
{
"root":[
{
"row":[
{
"name":"Foo",
"value":"Some value"
},
{
"name":"Bar",
"value":"Some other value"
}, (...)
]
},
{
"row":[
{
"name":"Foo",
"value":"Lorem"
},
{
"name":"Bar",
"value":"Ipsum"
}, (...)
]
}, (...)
]
}
我想使用Newtonsoft.Json将其反序列化为C#对象列表,以便名称与对象属性匹配,而值将为属性值。该类如下所示:
class Row
{
public string Foo { get; set; }
public string Bar { get; set; }
(...)
}
有什么想法吗?
答案 0 :(得分:2)
您可以使用自定义JsonConverter来处理此问题。在一个简单的示例下面,它需要进行一些null检查等,但这可以实现这个想法:
public class RowConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Row[]);
}
public override bool CanWrite => false;
public override bool CanRead => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return string.Empty;
}
else if (reader.TokenType == JsonToken.String)
{
return serializer.Deserialize(reader, objectType);
}
else
{
JObject obj = JObject.Load(reader);
var root = obj["root"];
if (root != null)
{
var rows = new List<Row>();
foreach (var item in root)
{
var row = item["row"];
var newRow = new Row();
foreach(var field in row)
{
// better use reflection here to convert name-value to property setter
if (field.Value<string>("name") == "Foo")
{
newRow.Foo = field["value"].Value<string>();
}
if (field.Value<string>("name") == "Bar")
{
newRow.Bar = field["value"].Value<string>();
}
}
rows.Add(newRow);
}
return rows.ToArray();
}
return null;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后在Row类上:
[JsonConverter(typeof(RowConverter))]
public class Row
{
public string Foo { get; set; }
public string Bar { get; set; }
}
如果需要将其包含在MVC中,请在Startup.cs(asp.net核心)中:
services
.AddMvc()
.AddJsonOptions(options => { options.SerializerSettings.Converters.Add(new RowConverter()); });
答案 1 :(得分:0)
作为一种选择,您可以将其转换为单个“行”属性的字典:
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
在创建动态对象之后:
private static dynamic DictionaryToObject(IDictionary<String, Object> dictionary)
{
var expandoObj = new ExpandoObject();
var expandoObjCollection = (ICollection<KeyValuePair<String, Object>>)expandoObj;
foreach (var keyValuePair in dictionary)
{
expandoObjCollection.Add(keyValuePair);
}
dynamic eoDynamic = expandoObj;
return eoDynamic;
}
private static T DictionaryToObject<T>(IDictionary<String, Object> dictionary) where T : class
{
return DictionaryToObject(dictionary) as T;
}
答案 2 :(得分:-1)
您可以创建如下所示的类,然后使用newtosnsoft
public class root
{
public List<row> row {get;set;}
}
public class row
{
public string name {get;set;}
public string value {get;set;}
}