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

时间:2015-09-02 19:40:13

标签: c# json serialization

我有一个调用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
            ]
        }
    }
]

3 个答案:

答案 0 :(得分:1)

因此,对于任何关心将Geometry Class更改为以下内容的人都解决了我的问题:

public class Geometry
{
        public string type { get; set; }
        public object coordinates { get; set; }
}

刚刚将列表更改为对象。然后在运行时,我可以检查对象是列表还是列表,然后继续。

答案 1 :(得分:1)

创建自定义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;
    }
}

答案 2 :(得分:0)

如果我理解并且您尝试将def portfolio_params params.require(:portfolio).permit(:nickname, :management_fee, investments_attributes: [:id, :ticker, :quantity, '_destroy']) end 反序列化为List<List<a>>,那么应该错误。您告诉它将其反序列化为序列化之前的其他内容。我建议传播一些与字符串一起的指示,以便您可以检查和反序列化为该类型,或者首先包装反序列化尝试和List<a>,然后如果失败则包装另一个。

每次更新修改

try