c# - 如何在c#中反序列化json数组

标签 c# .net json

我正在尝试反序列化以下 JSON 文件:http://komunikaty.tvp.pl/komunikatyxml/malopolskie/wszystkie/0?_format=json

我的 C# 代码:

MemoryStream stream1 = new MemoryStream();
StreamWriter writer = new StreamWriter(stream1);
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ApiRegionalne));
writer.Write(json);
writer.Flush();
stream1.Position = 0;
dane = (ApiRegionalne)ser.ReadObject(stream1);

还有我的类(class):

[DataContract]
public class newses
{
    public int id;
    public string title;
    public bool shortcut;
    public string content;
    public bool rso_alarm;
    public string rso_icon;
    public string longitude;
    public string latitude;
    public int water_level_value;
    public int water_level_warning_status_value;
    public int water_level_alarm_status_value;
    public int water_level_trend;
    public string river_name;
    public string location_name;
    public string type;
}

[DataContract]
public class ApiRegionalne
{
    [DataMember(Name = "newses")]
    public newses[] newses;
}

JSON 反序列化器不会抛出任何异常,但我的数据仍然为空。

我做错了什么?

最佳答案

您的基本问题是数据协定序列化器(DataContractSerializerDataContractJsonSerializer)是选择加入。如果使用 [DataContract] 标记类型,则还必须使用 [DataMember] 标记要序列化的成员,如 Using Data Contracts 中所述。 :

You can also explicitly create a data contract by using DataContractAttribute and DataMemberAttribute attributes. This is normally done by applying the DataContractAttribute attribute to the type. This attribute can be applied to classes, structures, and enumerations. The DataMemberAttribute attribute must then be applied to each member of the data contract type to indicate that it is a data member, that is, it should be serialized.

您尚未将 [DataMember] 应用于 newses 类型的任何成员,因此如果其成员被反序列化,则不会有任何成员。

第二个问题是您已将 water_level_trend 声明为 int,但它在 JSON 中显示为空字符串:

     "water_level_trend":"",

空字符串不能绑定(bind)到整数;如果您尝试,DataContractJsonSerializer 将抛出以下异常:

There was an error deserializing the object of type ApiRegionalne. The value '' cannot be parsed as the type 'Int32'.

由于您似乎想要使用数据协定属性显式标记您的类型,因此您可以使用站点 https://jsonutils.com/为您自动生成类型并应用所需的属性。您还可以选择自动对属性和类型名称进行驼峰式命名,从而与推荐的 .Net 样式保持一致:

[DataContract]
public class Pagination
{
    [DataMember(Name = "totalitems")]
    public int Totalitems { get; set; }

    [DataMember(Name = "itemsperpage")]
    public int Itemsperpage { get; set; }
}

[DataContract]
public class Six // Fixed name from 6
{
    [DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }

    [DataMember(Name = "city")]
    public string City { get; set; }

    [DataMember(Name = "slug_name")]
    public string SlugName { get; set; }
}

[DataContract]
public class Provinces
{
    [DataMember(Name = "6")]
    public Six Six { get; set; }
}

[DataContract]
public class News
{
    [DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "title")]
    public string Title { get; set; }

    [DataMember(Name = "shortcut")]
    public string Shortcut { get; set; }

    [DataMember(Name = "content")]
    public string Content { get; set; } // Fixed type from object

    [DataMember(Name = "rso_alarm")]
    public string RsoAlarm { get; set; }

    [DataMember(Name = "rso_icon")]
    public string RsoIcon { get; set; } // Fixed type from object

    [DataMember(Name = "valid_from")]
    public string ValidFrom { get; set; }

    [DataMember(Name = "0")]
    public string Zero { get; set; }  // Fixed name from 0

    [DataMember(Name = "valid_to")]
    public string ValidTo { get; set; }

    [DataMember(Name = "1")]
    public string One { get; set; } // Fixed name from 1

#if false
    // Removed since the correct type is unknown.
    [DataMember(Name = "repetition")]
    public object Repetition { get; set; }
#endif

    [DataMember(Name = "longitude")]
    public string Longitude { get; set; }

    [DataMember(Name = "latitude")]
    public string Latitude { get; set; }

    [DataMember(Name = "water_level_value")]
    public int WaterLevelValue { get; set; } // Fixed type to int

    [DataMember(Name = "water_level_warning_status_value")]
    public int WaterLevelWarningStatusValue { get; set; } // Fixed type to int

    [DataMember(Name = "water_level_alarm_status_value")]
    public int WaterLevelAlarmStatusValue { get; set; } // Fixed type to int

    [DataMember(Name = "water_level_trend")]
    public string WaterLevelTrend { get; set; } // This must remain a string since it appears as a non-numeric empty string in the JSON: "".

    [DataMember(Name = "river_name")]
    public string RiverName { get; set; }

    [DataMember(Name = "location_name")]
    public string LocationName { get; set; }

    [DataMember(Name = "created_at")]
    public string CreatedAt { get; set; }

    [DataMember(Name = "2")]
    public string Two { get; set; } // // Fixed name from 2

    [DataMember(Name = "updated_at")]
    public string UpdatedAt { get; set; }

    [DataMember(Name = "3")]
    public string Three { get; set; } // Fixed name from 3

    [DataMember(Name = "type")]
    public string Type { get; set; }

    [DataMember(Name = "provinces")]
    public Provinces Provinces { get; set; }
}

[DataContract]
public class ApiRegionalne
{
    [DataMember(Name = "pagination")]
    public Pagination Pagination { get; set; }

    [DataMember(Name = "newses")]
    public IList<News> Newses { get; set; }
}

请注意,有必要对自动生成的类型进行一些手动修复,例如将数字属性重命名为一些适当的非数字名称,例如11。此外,有必要将 JSON 中一些为 null 的属性的类型从 object 更改为更合适的类型,例如 string。上面注释了手动更改。

关于c# - 如何在c#中反序列化json数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46306002/

相关文章:

c# - 用于解析二进制消息包的字节流的高效 C# 字节队列

c# - 从列表或数据集中在选中的列表框中设置选中的项目

c# - 无法捕获 Invoke 在已编译表达式上抛出的异常

c# - 序列化 ArrayList 的 Arraylist

c# - 创建多行字符串的最佳语法

c# - 支持文档中包含哪些核心元素?

python - 类型 'KeyPoint'的对象不是JSON可序列化的opencv

javascript - 使用 getJSON 填充动画响应图像网格

php - 如何用jquery检查json数据返回是否为空

c# - 数组在 CLR 中有直接支持