簡體   English   中英

將JSON字符串序列化為C#對象時遇到問題

[英]Having issues serializing json string to c# object

我有一個調用Web服務的類,該類返回一個需要反序列化為C#對象的JSON字符串。 我成功地做到了; 但是,我遇到了無法確定最佳處理方式的情況。 更具體地說,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
            ]
        }
    }
]

因此,對於那些關心將Geometry類更改為以下內容的人來說,解決了我的問題:

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

只是將列表更改為對象。 然后在運行時,我可以檢查對象是列表列表還是僅列表,然后繼續。

創建一個自定義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一次,然后再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());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM