Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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
C# 无法处理集合反序列化错误_C#_Collections_Json.net - Fatal编程技术网

C# 无法处理集合反序列化错误

C# 无法处理集合反序列化错误,c#,collections,json.net,C#,Collections,Json.net,我试图处理一个不符合我的一些类的对象。我希望代码只在无效属性上执行并失败,但反序列化方法返回的是null对象 我在泛型实用程序类中使用此方法,该类将某些字符串反序列化为任何给定类型 从测试代码中,错误处理程序在无效日期和其他无效类型上正常工作,并返回具有默认.NET初始化值的对象 如果我更改(或注释)子对象中的Items集合,代码将正常工作 string json = "{\"Id\":8,\"CreatedByUserId\":0,\"CreatedOnDate\":\"2019X-Y02Z-

我试图处理一个不符合我的一些类的对象。我希望代码只在无效属性上执行并失败,但反序列化方法返回的是null对象

我在泛型实用程序类中使用此方法,该类将某些字符串反序列化为任何给定类型

从测试代码中,错误处理程序在无效日期和其他无效类型上正常工作,并返回具有默认.NET初始化值的对象

如果我更改(或注释)子对象中的Items集合,代码将正常工作

string json = "{\"Id\":8,\"CreatedByUserId\":0,\"CreatedOnDate\":\"2019X-Y02Z-W06T18:A51:05.783\",\"LastModifiedByUserId\":1,\"LastModifiedOnDate\":\"2019-03-12T17:00:34.82\",\"OperationData\":{\"IsActive\":true,\"Items\":[{\"_Id\":1,\"Id_Value\":0,\"Id\":1},{\"_Id\":2,\"Id\":2},{\"Id\":1,\"IsDeleted\":false,\"Content\":{}}]}}";

TestType test = DeserealizeContent(json);

/*The convertion utility*/ 
 private static TestType DeserealizeContent(string data)
        {
            var settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                MissingMemberHandling = MissingMemberHandling.Ignore,
                Error = HandleDeserializationError
            };
            var r = JsonConvert.DeserializeObject<TestType>(data, settings);
            return r;
        }
        public static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
        {
            errorArgs.ErrorContext.Handled = true;
        }

/*Supporting types*/
public class TestType {
        public int Id { get; set; }
        public DateTime CreatedOnDate { get; set; }
        public int CreatedByUserId { get; set; }
        public string Instructions { get; set; }
        public OperationDataType OperationData {get;set;}
    }

    public class OperationDataType {
        public bool IsActive { get; set; }
        public List<int> Items { get; set; }
    }

[代码>>字符串json<<代码>字符串json>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>:8,:8,:8,,,,,,,,,,,,,“运营数据”::,,,“2019X-X-X-Y02-Y-Y02Z-Y02Z-W0610-W06T18-W068:5:5:5:A51:A51:A51:1:1:1:1:5:5.781:5:5.781:5.781:5.783:5:5.783.783,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”,”eleted\':false,\'Content\':{}}]}; TestType test=DeserealizeContent(json); /*转换实用程序*/ 私有静态TestType DeserializeContent(字符串数据) { var设置=新的JsonSerializerSettings { NullValueHandling=NullValueHandling.Ignore, MissingMemberHandling=MissingMemberHandling.Ignore, Error=HandleDeserializationError }; var r=JsonConvert.DeserializeObject(数据、设置); 返回r; } public static void HandleDeserializationError(对象发送方,ErrorEventArgs errorArgs) { errorArgs.ErrorContext.Handled=true; } /*支撑类型*/ 公共类TestType{ 公共int Id{get;set;} 公共日期时间CreatedOnDate{get;set;} public int CreatedByUserId{get;set;} 公共字符串指令{get;set;} 公共操作数据类型操作数据{get;set;} } 公共类操作数据类型{ 公共bool IsActive{get;set;} 公共列表项{get;set;} } 我希望错误处理程序捕获异常并继续处理该过程,但反序列化最终只返回null

如果我将列表项更改为列表项,则正确解析结果

我的预期结果是: { “Id”:8, “CreatedByUserId”:0, “CreatedOnDate”:空, “LastModifiedByUserId”:1, “LastModifiedOnDate”:“2019-03-12T17:00:34.82”, “操作数据”:{ “IsActive”:是的, “项目”:空 } }

编辑-解决方案

Yair(贝娄)的建议有效。
从一个列表到另一个列表的更改工作正常,异常得到正确的处理。

json中的项不是int数组,所以您希望它是如何被列表的? Items是对象数组查看json格式:

{
    "Id": 8,
    "CreatedByUserId": 0,
    "CreatedOnDate": "2019X-Y02Z-W06T18:A51:05.783",
    "LastModifiedByUserId": 1,
    "LastModifiedOnDate": "2019-03-12T17:00:34.82",
    "OperationData": {
        "IsActive": true,
        "Items": [{
                "_Id": 1,
                "Id_Value": 0,
                "Id": 1
            }, {
                "_Id": 2,
                "Id": 2
            }, {
                "Id": 1,
                "IsDeleted": false,
                "Content": {}
            }
        ]
    }
}
您可以执行以下三项操作之一:

  • 将json内容作为字符串处理或映射,使项目为int数组[1,2,3]
  • 为包含所有所需字段的项创建项类,然后提取所需的int
  • 像现在一样将其作为对象获取,并使用reflection()获取所需的int
  • 您可以使用此功能进行反射:

    public static object GetPropValue(object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }
    
    然后像这样使用它:

    GetPropValue(test.OperationData.items[0], "Id")
    
    test.Id = jsonDeserialized["Id"];
    test.CreatedByUserId = jsonDeserialized["CreatedByUserId"];
    
    编辑 您可以使用此命令以通用方式反序列化json:

    Newtonsoft.Json.Linq.JObject jsonDeserialized  = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject<object>(json);
    
    等等


    根据您上次的评论,我发现如果我将
    列表项
    更改为
    列表项
    ,它会按照您的要求工作。它是一种具有原语类型和反序列化解析的东西。

    json中的项目不是int数组,那么您希望它是如何列表的呢? Items是对象数组查看json格式:

    {
        "Id": 8,
        "CreatedByUserId": 0,
        "CreatedOnDate": "2019X-Y02Z-W06T18:A51:05.783",
        "LastModifiedByUserId": 1,
        "LastModifiedOnDate": "2019-03-12T17:00:34.82",
        "OperationData": {
            "IsActive": true,
            "Items": [{
                    "_Id": 1,
                    "Id_Value": 0,
                    "Id": 1
                }, {
                    "_Id": 2,
                    "Id": 2
                }, {
                    "Id": 1,
                    "IsDeleted": false,
                    "Content": {}
                }
            ]
        }
    }
    
    您可以执行以下三项操作之一:

  • 将json内容作为字符串处理或映射,使项目为int数组[1,2,3]
  • 为包含所有所需字段的项创建项类,然后提取所需的int
  • 像现在一样将其作为对象获取,并使用reflection()获取所需的int
  • 您可以使用此功能进行反射:

    public static object GetPropValue(object src, string propName)
    {
        return src.GetType().GetProperty(propName).GetValue(src, null);
    }
    
    然后像这样使用它:

    GetPropValue(test.OperationData.items[0], "Id")
    
    test.Id = jsonDeserialized["Id"];
    test.CreatedByUserId = jsonDeserialized["CreatedByUserId"];
    
    编辑 您可以使用此命令以通用方式反序列化json:

    Newtonsoft.Json.Linq.JObject jsonDeserialized  = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject<object>(json);
    
    等等


    根据您上次的评论,我发现如果我将
    列表项
    更改为
    列表项
    ,它会按照您的要求工作。这是一种具有原语类型和反序列化解析功能的功能。

    感谢您的回答。我无法控制输入json字符串,因为我正在从API接收它。此外,如果json的某些部分没有得到正确解析(对于给定路径返回null),也可以。我的问题是,完全反序列化返回的是null对象,因为子类中的类型存在问题。在这个例子中,我想实现的是一种通用的反序列化方法,除了项目,因为存在不兼容。如果你不想要项目,你可以删除它们,为什么不把它作为对象列表保存呢。如果你仍然想删除它,你需要从字符串中删除它,或者看看我对答案的添加。谢谢你,你的建议在任何特定情况下都有效。我在这里试图实现的是一个反序列化方法,它会正常地失败,并将json字符串中的所有内容映射到给定的类型。实际上,发布的代码只是一个示例来说明失败的情况:当集合未能反序列化(如示例列表与列表不兼容)时,完整的反序列化方法将失败。我检测到此问题的根本原因是集合的类型发生了更改,由于内部错误导致所有解析都失败。因此,我的问题是,如果代码正在处理异常,为什么它在任何地方都能工作(如在无效日期中)但不是在无效的数组类型中?嗨,我发现从我读到的内容来看,它对int不起作用,可能是因为它试图将它反序列化为long,所以我更改了t