我正在使用一个返回json
的服务。
我有一个键值对象,其中键是string
,值是object
,我知道在哪里根据键投射对象。
它看起来像:
{
"key1": "This is key 1",
"key2": 12,
"key3": ["Key 3 first item", "Key 3 second item"]
}
对于简单类型(例如)strings
、long
、int
等,没有问题
当我收到array
(键3)时,问题就开始了。
我的c#代码看起来像这样:
Dictionary<string, object> values = GetValuesFromTheService();
string str = (string)values["key1"]; // Ok
long lng = (long)values["key2"]; // Ok
List<string> strs = (List<string>)values["key3"]; // BAD
key3实际上是JArray
,而不是List<string>
——我想这是因为我使用object
作为值,而不是更具体(List<object>
也会比JArray
更好)。
对此我能做些什么吗?
我在尝试(反)序列化一些自定义枚举时也遇到了类似的情况。对于解决方案,我创建了一个自定义的JsonConvertor。这是我使用的代码。。。
public class EnumerationConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var enm = (Enumeration)value;
writer.WriteValue(enm.Value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
{
return null;
}
int value;
if (reader.ValueType == typeof(Int64))
{
value = Convert.ToInt32(reader.Value);
}
else
{
value = (int)reader.Value;
}
return Enumeration.FromValueOrDefault(objectType, value);
}
public override bool CanConvert(Type objectType)
{
if (objectType.BaseType == null) return false;
return objectType.BaseType.Name == "Enumeration";
}
}
然后,当我想调用它并将json拉回到我的对象中时,这是一行。。。
JsonConvert.DeserializeObject<List<CustomObjectDto>>(req.Content.ReadAsStringAsync().Result, new EnumerationConverter());
好的是,它变得普遍可用,CustomObjectDto可以在其中有一个这个神奇字典的实例作为属性。。。甚至多个。。。并且将仅对根据转换器中的逻辑匹配的属性应用转换。。。希望能有所帮助。
这里有一个类似主题的链接-->http://blog.maskalik.com/asp-net/json-net-implement-custom-serialization/
您应该能够将整个对象解析为jObject,然后选择所需类型的键。这是未经测试的基本想法。
var j = JObject.Parse(GetValuesFromTheService());
string str = (string)j.SelectToken("key1");
long lng = (long)j.SelectToken("key2");
var strs = (List<string>)j.SelectToken("key3");
如果key3
是string
值的JArray
,则可以执行以下操作:
List<string> strs = ((JArray)values["key3"]).Select(t => t.Value<string>()).ToList();