我正在尝试反序列化以下 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 反序列化器不会抛出任何异常,但我的数据仍然为空。
我做错了什么?
最佳答案
您的基本问题是数据协定序列化器(DataContractSerializer
和 DataContractJsonSerializer
)是选择加入。如果使用 [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; }
}
请注意,有必要对自动生成的类型进行一些手动修复,例如将数字属性重命名为一些适当的非数字名称,例如1
到 1
。此外,有必要将 JSON 中一些为 null 的属性的类型从 object
更改为更合适的类型,例如 string
。上面注释了手动更改。
关于c# - 如何在c#中反序列化json数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46306002/