在将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
            ]
        }
    }
]

在将json字符串序列化为c#对象时存在问题

所以对于任何关心将几何类更改为以下解决我的问题的人:

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());
    }
}