在将json字符串序列化为c#对象时存在问题
本文关键字:对象 存在 问题 json 字符串 序列化 在将 | 更新日期: 2023-09-27 18:10:58
我有一个调用webservice的类,它返回一个JSON字符串,我需要将其反序列化为c#对象。我成功地做到了;然而,我遇到了一个场景,我不确定处理的最佳方式。更具体地说,JSON将返回List<List<object>>
或仅返回List<object>
。我有一个问题,当我反序列化,如果我的对象是List<object>
和JSON是List<List<object>>
。在这种情况下,抛出一个异常。
这是我要反序列化的类:
public class WorkOrderJson
{
public string type { get; set; }
public Properties properties { get; set; }
public Geometry geometry { get; set; }
}
public class Properties
{
public string FeatureType { get; set; }
public string WorkOrderID { get; set; }
public string EqEquipNo { get; set; }
}
对于Geometry类,返回的坐标是上面的问题。如果返回的JSON是List<List<object>>
,则序列化良好。
public class Geometry
{
public string type { get; set; }
public List<List<double>> coordinates { get; set; }
}
我是这样执行反序列化的:
WorkOrderJson workOrderJson = new JavaScriptSerializer().Deserialize<List<WorkOrderJson>>(responseString);
其中responseString
是从web服务返回的JSON字符串。希望这能说得通。如果有人遇到类似的问题,请提供任何帮助,我将不胜感激。
下面是List<List<object>>
的示例,其中coordinates
是列表:
[
{
"type": "Feature",
"properties": {
"FeatureType": "WORKORDER",
"WorkOrderID": "AMO172-2015-107",
"EqEquipNo": "AC-LIN-001"
},
"geometry": {
"type": "LineString",
"coordinates": [
[
-111.00041804208979,
33.0002148138019
],
[
-111.00027869450028,
33.000143209356054
]
]
},
"symbology": {
"color": "#990000",
"lineWidth": "8"
}
}
]
下面是List<object>
的一个例子:
[
{
"type": "Feature",
"properties": {
"FeatureType": "WORKORDER",
"WorkOrderID": "AMO172-2015-115",
"EqEquipNo": "AC-LIN-001"
},
"geometry": {
"type": "Point",
"coordinates": [
-111.00041804208979,
33.0002148138019
]
}
}
]
所以对于任何关心将几何类更改为以下解决我的问题的人:
public class Geometry
{
public string type { get; set; }
public object coordinates { get; set; }
}
刚刚将list更改为object。然后在运行时,我可以检查对象是列表的列表还是只是一个列表,然后继续。
创建自定义JavaScriptConverter并将其注册到JavaScriptSerializer中。
然后像这样反序列化:
var converter = new JavaScriptSerializer();
converter.RegisterConverters(new List<JavaScriptConverter>() {new GeometryConverter()});
var workOrderJson = converter.Deserialize<List<WorkOrderJson>>(response);
这个转换器可以工作:
public class GeometryConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>(new Type[] {typeof(Geometry)}); }
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
Geometry geometry = obj as Geometry;
if (geometry != null)
{
// Create the representation
var result = new Dictionary<string, object>();
if (geometry.coordinates.Count == 1)
{
result.Add("type", "Point");
result.Add("coordinates", geometry.coordinates[0]);
}
else if (geometry.coordinates.Count > 1)
{
result.Add("type", "LineString");
result.Add("coordinates", geometry.coordinates);
}
return result;
}
return new Dictionary<string, object>();
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
Geometry geometry = null;
if (type == typeof(Geometry))
{
geometry = new Geometry();
geometry.type = (string)dictionary["type"];
geometry.coordinates = new List<List<double>>();
if ( geometry.type == "Point")
{
ArrayList arrayList = (ArrayList)dictionary["coordinates"];
geometry.coordinates.Add(ConvertCoordinates(arrayList));
}
else if (geometry.type == "LineString")
{
geometry.type = "LineString";
ArrayList coordinatesList = (ArrayList)dictionary["coordinates"];
foreach (ArrayList arrayList in coordinatesList)
{
geometry.coordinates.Add(ConvertCoordinates(arrayList));
}
}
}
return geometry;
}
private List<double> ConvertCoordinates(ArrayList coordinates)
{
var list = new List<double>();
foreach (var coordinate in coordinates)
{
list.Add((double)System.Convert.ToDouble(coordinate));
}
return list;
}
}
如果我理解,你正试图将List<List<a>>
反序列化为List<a>
,它应该错误。你告诉它将它反序列化为序列化之前的东西之外的东西。我建议将它与字符串一起传播一些指示,以便您可以检查和反序列化为该类型,或者先将反序列化尝试和try
包装在一起,如果失败则先包装另一个。
编辑每次更新
public class WorkOrderJson<T>
{
public Geometry<T> geometry { get; set; }
public WorkOrderJson<List<T>> Promote()
{
var temp = new WorkOrderJson<List<T>>();
temp.geometry = geometry.Promote();
return temp;
}
}
public class Geometry<T>
{
public T coordinates { get; set; }
public Geometry<List<T>> Promote()
{
var temp = new Geometry<List<T>>();
temp.coordinates = new List<T>(){ coordinates };
return temp;
}
}
public List<WorkOrder<List<List<double>>>> Deserialize(string x)
{
try
{
return new JavaScriptSerializer().Deserialize<List<WorkOrderJson<List<List<double>>>>>(x);
}
catch(InvalidOperationException ex)
{
return new JavaScriptSerializer().Deserialize<List<WorkOrderJson<List<double>>>>(x).Select(workOrder => workOrder.Promote());
}
}