简体   繁体   English

如何从 JSON 反序列化?

[英]How do I deserialize from JSON?

I know this question has been asked several times, but I couldn't still fix it so here goes my own thread.我知道这个问题已经被问过好几次了,但我仍然无法解决它,所以这里有我自己的线程。

I have this JSON:我有这个 JSON:

[{"madde_id":"71690","kac":"0","kelime_no":"90805","cesit":"0","anlam_gor":"0","on_taki":null,"madde":"emprovizasyon","cesit_say":"0","anlam_say":"1","taki":null,"cogul_mu":"0","ozel_mi":"0","lisan_kodu":"13","lisan":"Fransızca improvisation","telaffuz":null,"birlesikler":null,"font":null,"madde_duz":"emprovizasyon","gosterim_tarihi":null,"anlamlarListe":[{"anlam_id":"106525","madde_id":"71690","anlam_sira":"1","fiil":"0","tipkes":"0","anlam":"Doğaçlama","gos":"0","ozelliklerListe":[{"ozellik_id":"19","tur":"3","tam_adi":"isim","kisa_adi":"a.","ekno":"30"}]}]}]

I converted it to a class in C#:我将它转换为 C# 中的 class:

    public class Class1
{

    public class OzelliklerListe
    {
        public string ozellik_id { get; set; }
        public string tur { get; set; }
        public string tam_adi { get; set; }
        public string kisa_adi { get; set; }
        public string ekno { get; set; }
    }

    public class AnlamlarListe
    {
        public string anlam_id { get; set; }
        public string madde_id { get; set; }
        public string anlam_sira { get; set; }
        public string fiil { get; set; }
        public string tipkes { get; set; }
        public string anlam { get; set; }
        public string gos { get; set; }
        public List<OzelliklerListe> ozelliklerListe { get; set; }
    }

    public class MyArray
    {
        public string madde_id { get; set; }
        public string kac { get; set; }
        public string kelime_no { get; set; }
        public string cesit { get; set; }
        public string anlam_gor { get; set; }
        public object on_taki { get; set; }
        public string madde { get; set; }
        public string cesit_say { get; set; }
        public string anlam_say { get; set; }
        public object taki { get; set; }
        public string cogul_mu { get; set; }
        public string ozel_mi { get; set; }
        public string lisan_kodu { get; set; }
        public string lisan { get; set; }
        public object telaffuz { get; set; }
        public object birlesikler { get; set; }
        public object font { get; set; }
        public string madde_duz { get; set; }
        public object gosterim_tarihi { get; set; }
        public List<AnlamlarListe> anlamlarListe { get; set; }
    }

    public class Root
    {
        public List<MyArray> MyArray { get; set; }
    }
}

And I have this code to deserialize it:我有这个代码来反序列化它:

        [Command("tdk")]
    public async Task Define(string word)
    {
        var client = new HttpClient();
        var response = await client.GetStringAsync($"https://sozluk.gov.tr/gts?ara=" + word);

        
        Class1.Root obj = JsonConvert.DeserializeObject<Class1.Root>(response);
        

        foreach (var item in obj.MyArray)
        {
            await ReplyAsync(item.madde_id.ToString());
            await ReplyAsync(item.kac.ToString());
            await ReplyAsync(item.kelime_no.ToString());
            await ReplyAsync(item.cesit.ToString());
            await ReplyAsync(item.anlam_gor.ToString());
            await ReplyAsync(item.on_taki.ToString());
            await ReplyAsync(item.cogul_mu.ToString());
            await ReplyAsync(item.ozel_mi.ToString());
            await ReplyAsync(item.lisan_kodu.ToString());
            await ReplyAsync(item.lisan.ToString());
            await ReplyAsync(item.telaffuz.ToString());
            await ReplyAsync(item.madde.ToString());
            await ReplyAsync(item.birlesikler.ToString());
            await ReplyAsync(item.font.ToString());
            await ReplyAsync(item.madde_duz.ToString());
            await ReplyAsync(item.gosterim_tarihi.ToString());
            foreach (var item1 in item.anlamlarListe)
            {
                await ReplyAsync(item1.anlam_id.ToString());
                await ReplyAsync(item1.madde_id.ToString());
                await ReplyAsync(item1.anlam_sira.ToString());
                await ReplyAsync(item1.fiil.ToString());
                await ReplyAsync(item1.tipkes.ToString());
                await ReplyAsync(item1.anlam.ToString());
                await ReplyAsync(item1.gos.ToString());
                foreach (var item2 in item1.ozelliklerListe)
                {
                    await ReplyAsync(item2.ozellik_id.ToString());
                    await ReplyAsync(item2.tur.ToString());
                    await ReplyAsync(item2.tam_adi.ToString());
                    await ReplyAsync(item2.kisa_adi.ToString());
                    await ReplyAsync(item2.ekno.ToString());
                    
                }
            }
        }
    }

But it doesn't work.但它不起作用。 I get this error:我收到此错误:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Template.Modules.APIs.Class1+Root' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.

What am I missing?我错过了什么? Any help is appreciated.任何帮助表示赞赏。 I am new to coding, I don't know how to do this properly.我是编码新手,我不知道如何正确执行此操作。

I'd suggest, that since you deserialize object "Class1.Root", the JSON should start with JSONObject containing one array MyArray.我建议,既然您反序列化 object “Class1.Root”,那么 JSON 应该以包含一个数组 MyArray 的 JSONObject 开头。 The object structure as is, [ {... } ] should be { MyArray: [ {... } ] } Opposite approach - dont deserialize into Class1.Root , but directly into List<MyArray> , so change JsonConvert.DeserializeObject<Class1.Root>(response); Class1.Root结构原样, [ {... } ]应该是 { List<MyArray> { MyArray: [ {... } ] } JsonConvert.DeserializeObject<Class1.Root>(response); into JsonConvert.DeserializeObject<List<MyArray>>(response);进入JsonConvert.DeserializeObject<List<MyArray>>(response);

I suggest you check out https://app.quicktype.io/# It will generate the model classes and serialize/deserialize classes for you from the JSON.我建议您查看https://app.quicktype.io/#它将生成 model 类并从 Z0ECD11C1D7A287401D148A23BBD7A2F 为您序列化/反序列化类。 I would not take them "as is" after generation, but they put you in the ballpark, save a bunch of typing, and drive consistency in the model classes.我不会在一代之后“按原样”接受它们,但它们会让你进入球场,节省大量打字,并在 model 类中保持一致性。

I ran your json sample through the site ( https://app.quicktype.io?share=M7ysVSQFRP6Pj2KkIw8W ).我通过站点运行了您的 json 示例( https://app.quicktype.io?share=M7ysVSQFRP6Pj2KIw8 )。 Here is the resulting code.这是生成的代码。

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using StackExample;
//
//    var welcome = Welcome.FromJson(jsonString);

namespace StackExample
{
using System;
using System.Collections.Generic;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public partial class Welcome
{
    [JsonProperty("madde_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long MaddeId { get; set; }

    [JsonProperty("kac")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Kac { get; set; }

    [JsonProperty("kelime_no")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long KelimeNo { get; set; }

    [JsonProperty("cesit")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Cesit { get; set; }

    [JsonProperty("anlam_gor")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long AnlamGor { get; set; }

    [JsonProperty("on_taki")]
    public object OnTaki { get; set; }

    [JsonProperty("madde")]
    public string Madde { get; set; }

    [JsonProperty("cesit_say")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long CesitSay { get; set; }

    [JsonProperty("anlam_say")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long AnlamSay { get; set; }

    [JsonProperty("taki")]
    public object Taki { get; set; }

    [JsonProperty("cogul_mu")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long CogulMu { get; set; }

    [JsonProperty("ozel_mi")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long OzelMi { get; set; }

    [JsonProperty("lisan_kodu")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long LisanKodu { get; set; }

    [JsonProperty("lisan")]
    public string Lisan { get; set; }

    [JsonProperty("telaffuz")]
    public object Telaffuz { get; set; }

    [JsonProperty("birlesikler")]
    public object Birlesikler { get; set; }

    [JsonProperty("font")]
    public object Font { get; set; }

    [JsonProperty("madde_duz")]
    public string MaddeDuz { get; set; }

    [JsonProperty("gosterim_tarihi")]
    public object GosterimTarihi { get; set; }

    [JsonProperty("anlamlarListe")]
    public List<AnlamlarListe> AnlamlarListe { get; set; }
}

public partial class AnlamlarListe
{
    [JsonProperty("anlam_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long AnlamId { get; set; }

    [JsonProperty("madde_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long MaddeId { get; set; }

    [JsonProperty("anlam_sira")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long AnlamSira { get; set; }

    [JsonProperty("fiil")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Fiil { get; set; }

    [JsonProperty("tipkes")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Tipkes { get; set; }

    [JsonProperty("anlam")]
    public string Anlam { get; set; }

    [JsonProperty("gos")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Gos { get; set; }

    [JsonProperty("ozelliklerListe")]
    public List<OzelliklerListe> OzelliklerListe { get; set; }
}

public partial class OzelliklerListe
{
    [JsonProperty("ozellik_id")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long OzellikId { get; set; }

    [JsonProperty("tur")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Tur { get; set; }

    [JsonProperty("tam_adi")]
    public string TamAdi { get; set; }

    [JsonProperty("kisa_adi")]
    public string KisaAdi { get; set; }

    [JsonProperty("ekno")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Ekno { get; set; }
}

public partial class Welcome
{
    public static List<Welcome> FromJson(string json) => 
JsonConvert.DeserializeObject<List<Welcome>>(json, StackExample.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this List<Welcome> self) => 
JsonConvert.SerializeObject(self, StackExample.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new 
JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters =
        {
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal 
}
        },
    };
}

internal class ParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, 
JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        long l;
        if (Int64.TryParse(value, out l))
        {
            return l;
        }
        throw new Exception("Cannot unmarshal type long");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, 
JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (long)untypedValue;
        serializer.Serialize(writer, value.ToString());
        return;
    }

    public static readonly ParseStringConverter Singleton = new 
ParseStringConverter();
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM