我试图处理反密封的对象,该对象不符合我的某些课程。我希望代码能够执行并仅在无效属性上失败,但是反实现方法返回的是空对象。
我在泛型实用程序类中使用此方法,该类将某些字符串反实现为任何给定类型。
根据测试代码,错误处理程序可以在无效日期和其他无效类型上正常工作,并返回具有默认.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; }
}
我原本希望错误处理程序能够捕获异常并继续执行该过程,但是反现实化最终只会返回null。
如果我将“列表项”更改为“列表项”,则结果将被正确解析。
我的预期结果是: { “ Id”:8 “ CreatedByUserId”:0, “ CreatedOnDate”:null, “ LastModifiedByUserId”:1 “ LastModifiedOnDate”:“ 2019-03-12T17:00:34.82”, “ OperationData”:{ “ IsActive”:是, “项目”:null } }
编辑-解决方法
Yair(bellow)的建议起作用了。 从列表更改为列表可以按预期工作,并且可以正确处理异常。
答案 0 :(得分:0)
您的json中的项目不是int数组,因此您希望它如何成为List? 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")
编辑 您可以使用此方法以通用方式反序列化json:
Newtonsoft.Json.Linq.JObject jsonDeserialized = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject<object>(json);
然后
您可以手动将其映射,也可以使用自动映射器将其映射到所需的新TestType测试中,而无需包含项目。
您可以获得以下值:
test.Id = jsonDeserialized["Id"];
test.CreatedByUserId = jsonDeserialized["CreatedByUserId"];
以此类推
根据您的最后一条评论,我发现如果将List<int> Items
更改为List<long> Items
,它会按您的意愿工作。这是具有原始类型和反序列化功能的解析。