You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写通用JSON反序列化方法?解决Newtonsoft.Json序列化异常

JSON反序列化错误解决方法

错误信息

Newtonsoft.Json.JsonSerializationException: '无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.IEnumerable`1[ClientAddressWFA.Models.Address]',因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。
要修复此错误,请将JSON改为JSON数组(例如[1,2,3]),或者更改反序列化类型,使其成为可从JSON对象反序列化的普通.NET类型(例如不是整数等基元类型,也不是数组或List等集合类型)。也可以向该类型添加JsonObjectAttribute以强制其从JSON对象反序列化。

通用反序列化方法代码

public static async Task<IEnumerable<T>> JsonDeserialize<T>(string uri)
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync(uri);

    var content = await response.Content.ReadAsStreamAsync();

    StreamReader reader = new StreamReader(content);
    JsonReader jReader = new JsonTextReader(reader);

    JsonSerializer jSer = new JsonSerializer();

    return jSer.Deserialize<IEnumerable<T>>(jReader);
}

API响应结构

API返回的是一个FeatureCollection对象,而非直接的地址数组,结构大致如下:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { /* 对应Address模型的字段数据 */ },
      /* 其他无关字段 */
    }
  ]
}

Address模型代码

public class Address
{
    [JsonProperty("id")]
    public int Id;

    [JsonProperty("streetAddress")]
    public int StreetAddress;

    [JsonProperty("streetName")]
    public string StreetName;

    [JsonProperty("buildingNumber")]
    public int BuildingNumber;

    [JsonProperty("additionalBuildingNumber")]
    public string AdditionalBuildingNumber;

    [JsonProperty("fullAddress")]
    public string FullAddress;

    [JsonProperty("zipCode")]
    public int ZipCode;

    [JsonProperty("coordinateX")]
    public double CoordinateX;

    [JsonProperty("coordinateY")]
    public double CoordinateY;

    [JsonProperty("sozraum")]
    public int Sozraum;

    [JsonProperty("sozialraum")]
    public int Sozialraum;

    [JsonProperty("lebraum")]
    public int Lebraum;

    [JsonProperty("lebensraum")]
    public int Lebensraum;

    [JsonProperty("stimmbezirk")]
    public int Stimmbezirk;

    [JsonProperty("hnr_nur_fb62")]
    public string HnrNurFb62;

    [JsonProperty("gerade")]
    public string Gerade;

    [JsonProperty("district")]
    public string District;

    [JsonProperty("districtNumber")]
    public string DistrictNumber;

    [JsonProperty("wkb_geometry")]
    public string WkbGeometry;

    [JsonProperty("isMain")]
    public bool IsMain;
}

解决方案

方法1:创建匹配API响应的根模型

新增两个类适配API响应结构:

public class FeatureCollection
{
    [JsonProperty("features")]
    public List<Feature> Features { get; set; }
}

public class Feature
{
    [JsonProperty("properties")]
    public Address Properties { get; set; }
}

调用时先反序列化为FeatureCollection,再提取地址集合:

var featureCollection = await JsonDeserialize<FeatureCollection>(uri);
IEnumerable<Address> addresses = featureCollection.Features.Select(f => f.Properties);

方法2:直接解析JSON对象提取数组

无需新增模型,修改反序列化方法直接提取目标数组:

public static async Task<IEnumerable<T>> JsonDeserialize<T>(string uri)
{
    using HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync(uri);
    string json = await response.Content.ReadAsStringAsync();
    
    JObject jsonObj = JObject.Parse(json);
    JArray featuresArray = (JArray)jsonObj["features"];
    
    return featuresArray.Select(f => f["properties"].ToObject<T>());
}

核心错误原因

原方法试图将整个JSON对象直接反序列化为集合类型,但API返回的是包含数组的外层对象,而非数组本身,导致序列化失败。

内容的提问来源于stack exchange,提问作者Goga Gate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:25:28