是否有可能让JObject.Parse忽略缺少的字段?
从下面的示例中,您可以看到我已经声明了一个类Address
并使用JsonProperty
来指定备用字段名称。
我提供了3个示例,有3个JSON字符串,它们的结构略有不同,只有示例1匹配并返回一个对象,示例2和3返回null,因为有一个缺少的字段。
有没有办法使用其他JsonProperty来允许它们被忽略,如果没有提供?
public class Address
{
[JsonProperty("flat_number")]
public string FlatNumber { get; set; }
[JsonProperty("house_number")]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
private static T TryParse<T>(string json) where T : new()
{
var jSchemaGenerator = new JSchemaGenerator();
const string license = "license";
License.RegisterLicense(license);
var jSchema = jSchemaGenerator.Generate(typeof(T));
var jObject = JObject.Parse(json);
return jObject.IsValid(jSchema) ? JsonConvert.DeserializeObject<T>(json) : default(T);
}
//Example 1 with house_number and flat_number
const string json = "{\"house_number\":\"40\",\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 2 with house_number but not flat_number
//const string json = "{\"house_number\":\"40\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
//Example 3 with flat_number but not house_number
//const string json = "{\"flat_number\":\"82\",\"address\":\"Somewhere\",\"address2\":\"Over\",\"town\":\"There\",\"postcode\":\"ZZ991AA\"}";
var tryParse = TryParse<AddressTest>(json);
if (tryParse != null)
{
}
您可以使用JsonSerializerSettings来执行此操作。这将忽略您缺少的成员。
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
如果你的json包含一些键/值对作为动态意味着你不知道这些键/值对是否存在于json中
如果你的对象没有修复,数据必须是可配置的,那么Newtonsoft.json有一个功能可以在这里使用,那就是[JsonExtensionData]
。 Read more
现在,在序列化对象时会写入扩展数据。读取和写入扩展数据可以自动往返所有JSON,而无需将每个属性添加到要反序列化的.NET类型。只声明您感兴趣的属性,并让扩展数据完成其余的工作。
现在你的house_number
和flat_number
将被收集在[JsonExtensionData]
,所以你不再需要处理丢失的领域了。
所以你的Address
课程将是
public class Address
{
[JsonExtensionData]
public IDictionary<string, JsonToken> extensionData { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}
经过一点挖掘后,我发现了一个允许忽略空值的JsonProperty,通过将NullValueHandling = NullValueHandling.Ignore
应用于FlatNumber和HouseNumber,所有示例都返回一个对象。因此,根据下面的示例修改Address
类与我的原始代码一起使用。
public class Address
{
[JsonProperty("flat_number", NullValueHandling = NullValueHandling.Ignore)]
public string FlatNumber { get; set; }
[JsonProperty("house_number", NullValueHandling = NullValueHandling.Ignore)]
public string HouseNumber { get; set; }
[JsonProperty("address")]
public string Address1 { get; set; }
[JsonProperty("address2")]
public string Address2 { get; set; }
[JsonProperty("town")]
public string Town { get; set; }
[JsonProperty("postcode")]
public string Postcode { get; set; }
}