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