做一个windows服务,调用高德地图的WebAPI进行逆地理解析(通过经纬度获取地理信息),返回的JSON格式的属性类型不固定,不怎么该怎么反序列化?
例如,株洲市和上海市的JSON格式就不一样,株洲市的city是字符串类型,而上海市是数组类型。如果在js这种弱类型语言里不会报错,但是c#会报无法格式无法转换。把实例类的属性设置成dynamic类型也不行。请教各位大佬应该怎么办,city属性应该是什么类型?
如果用的是 Newtonsoft.Json,可以自己实现一个 JsonConverter,参考 C# Newtonsoft serialize property that is an array and a string
实现 CustomArrayConverter
public class CustomArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsAssignableTo(typeof(IEnumerable<T>));
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
Console.WriteLine("token.Type: " + token.Type);
if (token.Type == JTokenType.Array)
return token.ToObject<List<T>>();
return new List<T> { token.ToObject<T>() };
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
定义 Location
public class Location
{
public IEnumerable<string> City { get; set; }
}
反序列化时使用 CustomArrayConverter
var jons = "{ \"city\": \"杭州\" }";
var location = JsonConvert.DeserializeObject<Location>(
jons,
new JsonSerializerSettings
{
Converters = new[] { new CustomArrayConverter<string>() }
});var jons = "{ \"city\": \"杭州\" }";
var location = JsonConvert.DeserializeObject<Location>(
jons,
new JsonSerializerSettings
{
Converters = new[] { new CustomArrayConverter<string>() }
});
如果不想这么麻烦,可以将 json 字符串中的 "city": []
替换为 \"city\": \"\"
JObject o = JObject.Parse(@"{ 'CPU': 'Intel', 'Drives': [ 'DVD read/writer', '500 gigabyte hard drive' ] }"); string cpu = (string)o["CPU"]; // Intel string firstDrive = (string)o["Drives"][0]; // DVD read/writer IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList(); // DVD read/writer // 500 gigabyte hard drive
将City属性定义为object类型,如果用的是Newtonsoft.Json,字符串会正常解析为字符串,数组会解析成JArray
用Newtonsoft.Json 一个节点一个节点的解,每次解之前先判断节点是否存在,Newtonsoft.Json可以很方便的判断这个,存在就尝试提取值,说白了就是没法统一反序列化出来,基本就是硬编码。一般情况下不需要全解出来,提取自己需要的即可,也没有必要。
不过,好像现在好得多了,输出格式应该有统一的格式了,也有官方SDK。