首页 新闻 会员 周边 捐助

C#反序列化的问题

0
悬赏园豆:20 [已解决问题] 解决于 2024-02-05 09:41

做一个windows服务,调用高德地图的WebAPI进行逆地理解析(通过经纬度获取地理信息),返回的JSON格式的属性类型不固定,不怎么该怎么反序列化?

例如,株洲市和上海市的JSON格式就不一样,株洲市的city是字符串类型,而上海市是数组类型。如果在js这种弱类型语言里不会报错,但是c#会报无法格式无法转换。把实例类的属性设置成dynamic类型也不行。请教各位大佬应该怎么办,city属性应该是什么类型?

teagueli的主页 teagueli | 初学一级 | 园豆:75
提问于:2022-07-31 09:15
< >
分享
最佳答案
0

如果用的是 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>() }
    });
收获园豆:20
dudu | 高人七级 |园豆:29618 | 2022-07-31 11:48

如果不想这么麻烦,可以将 json 字符串中的 "city": [] 替换为 \"city\": \"\"

dudu | 园豆:29618 (高人七级) | 2022-07-31 11:49
其他回答(3)
0
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
小小高 | 园豆:1307 (小虾三级) | 2022-08-02 18:47
0

将City属性定义为object类型,如果用的是Newtonsoft.Json,字符串会正常解析为字符串,数组会解析成JArray

izan | 园豆:205 (菜鸟二级) | 2022-08-23 17:38
0

用Newtonsoft.Json 一个节点一个节点的解,每次解之前先判断节点是否存在,Newtonsoft.Json可以很方便的判断这个,存在就尝试提取值,说白了就是没法统一反序列化出来,基本就是硬编码。一般情况下不需要全解出来,提取自己需要的即可,也没有必要。
不过,好像现在好得多了,输出格式应该有统一的格式了,也有官方SDK。

Adming | 园豆:119 (初学一级) | 2022-09-04 19:25
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册