0

是否可以让 JObject.Parse 忽略缺失的字段?

从下面的示例中,您可以看到我已经声明了一个类AddressJsonProperty用于指定备用字段名称。

我提供了 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)
{

}
4

3 回答 3

1

您可以使用 JsonSerializerSettings 来执行此操作。这将忽略您丢失的成员。

var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;

JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);
于 2018-10-30T11:22:29.673 回答
0

如果您的 json 包含一些键/值对作为动态意味着您不知道这些键/值对是否存在于 json 中

如果您的对象不是固定的并且数据必须是可配置的,那么 Newtonsoft.json 有一个可以在这里使用的功能,那就是[JsonExtensionData]. 阅读更多

现在在序列化对象时写入扩展数据。读取和写入扩展数据可以自动往返所有 JSON,而无需将每个属性添加到要反序列化的 .NET 类型。只声明您感兴趣的属性,让扩展数据完成其余的工作。

现在您的house_numberflat_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; }
}
于 2018-10-30T11:45:40.753 回答
-1

经过更多的挖掘,我发现了一个允许忽略空值的 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; }
}
于 2018-10-30T12:04:43.767 回答