Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将json字符串序列化为c#对象时出现问题_C#_Json_Serialization - Fatal编程技术网

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

将json字符串序列化为c#对象时出现问题,c#,json,serialization,C#,Json,Serialization,我有一个调用webservice的类,它返回一个JSON字符串,我需要将该字符串反序列化为C#对象。我成功地做到了这一点;然而,我遇到了一个情景,我不确定确切地说是最好的处理方式。更具体地说,JSON要么返回列表,要么只返回列表。如果我的对象是List,而JSON是List,那么我在反序列化时遇到问题。在这种情况下,将引发异常 这是我正在尝试反序列化的类: public class WorkOrderJson { public string type { get;

我有一个调用webservice的类,它返回一个JSON字符串,我需要将该字符串反序列化为C#对象。我成功地做到了这一点;然而,我遇到了一个情景,我不确定确切地说是最好的处理方式。更具体地说,JSON要么返回
列表
,要么只返回
列表
。如果我的对象是
List
,而JSON是
List
,那么我在反序列化时遇到问题。在这种情况下,将引发异常

这是我正在尝试反序列化的类:

    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是一个
列表
,则可以进行序列化

    public class Geometry
    {
        public string type { get; set; }
        public List<List<double>> coordinates { get; set; }
    }
下面是
列表的一个示例:


如果我理解并且您试图将
列表
反序列化为
列表
,则应该会出错。您告诉它将其反序列化为与序列化之前不同的内容。我建议您传播它与字符串在一起的一些指示,以便您可以检查并反序列化为该类型,或者包装反序列化尝试,然后
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());
    }
}
public class WorkOrderJson
{
公共几何体{get;set;}
公共工作促进
{
var temp=新的WorkOrderJson();
temp.geometry=geometry.Promote();
返回温度;
}
}
公共课几何
{
公共T坐标{get;set;}
公共几何推广()
{
var temp=新几何体();
temp.coordinates=新列表(){coordinates};
返回温度;
}
}
公共列表反序列化(字符串x)
{
尝试
{
返回新的JavaScriptSerializer();
}
捕获(无效操作异常ex)
{
返回新的JavaScriptSerializer();
}
}

因此,对于任何关心将几何体类更改为以下内容的人,我的问题已经得到了解决:

public class Geometry
{
        public string type { get; set; }
        public object coordinates { get; set; }
}
刚刚将列表更改为对象。然后在运行时,我可以检查对象是列表列表还是仅仅是列表,然后继续操作。

创建一个自定义对象,并将其注册到JavaScriptSerializer

然后,您将进行如下反序列化:

var converter = new JavaScriptSerializer();
converter.RegisterConverters(new List<JavaScriptConverter>() {new GeometryConverter()});
var workOrderJson = converter.Deserialize<List<WorkOrderJson>>(response);
var converter=newJavaScriptSerializer();
registerConverter(新列表(){new GeometryConverter()});
var workOrderJson=转换器。反序列化(响应);
这个转换器可以工作:

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;
    }
}
公共类GeometryConverter:JavaScriptConverter { 公共覆盖IEnumerable SupportedTypes { 获取{返回新列表(新类型[]{typeof(几何体)});} } 公共重写IDictionary序列化(对象obj、JavaScriptSerializer序列化程序) { 几何体=作为几何体的obj; 如果(几何体!=null) { //创建表示 var result=newdictionary(); if(geometry.coordinates.Count==1) { 结果。添加(“类型”、“点”); 结果。添加(“坐标”,几何。坐标[0]); } 如果(geometry.coordinates.Count>1),则为else { 结果。添加(“类型”、“行字符串”); 结果。添加(“坐标”,几何。坐标); } 返回结果; } 返回新字典(); } 公共重写对象反序列化(IDictionary dictionary、类型、JavaScriptSerializer序列化程序) { if(dictionary==null) 抛出新的ArgumentNullException(“字典”); 几何=空; if(类型==类型(几何体)) { 几何体=新几何体(); geometry.type=(字符串)字典[“type”]; geometry.coordinates=新列表(); 如果(geometry.type==“点”) { ArrayList ArrayList=(ArrayList)字典[“坐标”]; geometry.coordinates.Add(ConvertCoordinates(arrayList)); } else if(geometry.type==“LineString”) { geometry.type=“LineString”; ArrayList coordinates List=(ArrayList)字典[“坐标”]; foreach(协调列表中的ArrayList ArrayList) { geometry.coordinates.Add(ConvertCoordinates(arrayList)); } } } 返回几何; } 私有列表坐标(ArrayList坐标) { var list=新列表(); foreach(坐标中的变量坐标) { list.Add((双)System.Convert.ToDouble(坐标)); } 退货清单; } }
是的,我同意,它应该会失败,但问题是json返回字符串是list(list(object))和list(object)的“坐标”,所以当我不知道返回是list(list(object))还是list(object)时,如何创建Geometry类。问题是如何处理这两个问题?@Maxqueue通过您的更新,我更了解问题所在。看起来您找到了解决方案,但另一种方法是参数化
WorkOrder
(和
Geometry
),使其成为
WorkOrder
WorkOrder
尝试
反序列化为第一个,如果失败,则反序列化为第二个。但是,在返回时(一个元素的列表),您需要将
列表
案例“升级”为
列表
,因此它们是相同的类型。但是,您将有两个同名变量。@Maxqueue我用我建议的示例更新了答案。它并不漂亮,它是否值得取决于您的用例。但是,让一个裸露的
对象
四处浮动,并且可能需要打开它是
列表
还是
列表
也不是很吸引人。这个工具很好,只需粘贴你的
public class Geometry
{
        public string type { get; set; }
        public object coordinates { get; set; }
}
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;
    }
}