无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“ConsoleAppTest01.Location”,因为该类型需要 JSON 对象

Posted

技术标签:

【中文标题】无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“ConsoleAppTest01.Location”,因为该类型需要 JSON 对象【英文标题】:Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleAppTest01.Location' because the type requires a JSON object 【发布时间】:2022-01-07 14:59:06 【问题描述】:

无法弄清楚为什么我会收到此异常:

可以在此处查看 JSON 响应(不用担心我稍后会更新 API 密钥): http://dataservice.accuweather.com/locations/v1/postalcodes/search?apikey=RUuBWKtaUKRJC4GtWkjGDuhStOZblr78&q=12065

我的代码如下所示:

public class Location

    public Locality[] Property1  get; set; 


public class Locality

    public int Version  get; set; 
    public string Key  get; set; 
    public string Type  get; set; 
    public int Rank  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 
    public string PrimaryPostalCode  get; set; 
    public Region Region  get; set; 
    public Country Country  get; set; 
    public Administrativearea AdministrativeArea  get; set; 
    public Timezone TimeZone  get; set; 
    public Geoposition GeoPosition  get; set; 
    public bool IsAlias  get; set; 
    public Parentcity ParentCity  get; set; 
    public Supplementaladminarea[] SupplementalAdminAreas  get; set; 
    public string[] DataSets  get; set; 


public class Region

    public string ID  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 


public class Country

    public string ID  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 


public class Administrativearea

    public string ID  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 
    public int Level  get; set; 
    public string LocalizedType  get; set; 
    public string EnglishType  get; set; 
    public string CountryID  get; set; 


public class Timezone

    public string Code  get; set; 
    public string Name  get; set; 
    public float GmtOffset  get; set; 
    public bool IsDaylightSaving  get; set; 
    public DateTime NextOffsetChange  get; set; 


public class Geoposition

    public float Latitude  get; set; 
    public float Longitude  get; set; 
    public Elevation Elevation  get; set; 


public class Elevation

    public Metric Metric  get; set; 
    public Imperial Imperial  get; set; 


public class Metric

    public float Value  get; set; 
    public string Unit  get; set; 
    public int UnitType  get; set; 


public class Imperial

    public float Value  get; set; 
    public string Unit  get; set; 
    public int UnitType  get; set; 


public class Parentcity

    public string Key  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 


public class Supplementaladminarea

    public int Level  get; set; 
    public string LocalizedName  get; set; 
    public string EnglishName  get; set; 

在 Main() 中

static void Main(string[] args)
    
        string apiUrl = $"http://dataservice.accuweather.com";
        
        Console.Write("Enter ZipCode: ");
        string zip = Console.ReadLine();

        string locationUri = $"apiUrl/locations/v1/postalcodes/search?apikey=APIKEY&q=zip";            

        Location locationData = GetLocation<Location>(locationUri);
                    
    

GetLocation() 看起来像:

   protected static T GetLocation<T>(string uri)
    
        T result;

        HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
        request.Method = "GET";

        HttpWebResponse response = request.GetResponse() as HttpWebResponse;

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        
            string jsonString = reader.ReadToEnd();
            result = JsonConvert.DeserializeObject<T>(jsonString);
        

        return result;
    

【问题讨论】:

【参考方案1】:

从 accuweather 返回的 Json 以 [ 开头,因此它必须是一个数组,但您已告诉 JsonConvert 反序列化对象位置;这不是一个数组(json 必须以 开头,对象 deser 才能工作)

快速浏览一下(在手机上,很难消化完整的 json 并在小屏幕上 100% 将其映射到您的课程)似乎您想要的是 Locality[],而不是 Location..

..但我建议您将 json 粘贴到 http://QuickType.io 并使用它为您创建的类;他们会马上工作的

甚至更好;很可能 accuweather 发布了一个 swagger/open api 规范,您可以通过 AutoRest 或 nSwag 之类的东西运行,并让这些工具为您生成一整套客户端存根,因此它实际上是一行代码将对象发送到 api ,得到回应,阅读并应得它并给你答案

【讨论】:

谢谢!这真的很有帮助。【参考方案2】:

您的 json 根目录是 List,而不是对象。尝试使用这个

List<Locality> locationData = GetLocation<List<Locality>>(locationUri);

【讨论】:

以上是关于无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“ConsoleAppTest01.Location”,因为该类型需要 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“ConsoleAppTest01.Location”,因为该类型需要 JSON 对象

无法将当前 JSON 数组(例如 [1,2,3])反序列化为具有复杂和嵌套对象的类型

无法将当前 JSON 数组(例如 [1,2,3])反序列化为“System.Collections.Generic.Dictionary”类型

无法将当前 JSON 对象(例如 "name":"value")反序列化为类型“Value[]”,因为该类型需要 JSON 数组(例如 [1,2,3])

无法将当前JSON数组(例如[1,2,3])反序列化为“模型”类型

无法将 JSON 数组(例如 [1,2,3])反序列化为类型 ' ',因为类型需要 JSON 对象(例如 "name":"value")才能正确反序列化