使用Newtonsoft.Json合并对象时,如何忽略空字符串值?

时间:2015-04-06 16:40:41

标签: c# json serialization json.net

我有一个在C#中定义为类的数据模型。我需要使用JObject.Merge合并两个对象,但在一个特定属性的情况下,我需要忽略第二个对象的空字符串值,类似于忽略空值的方式。是否有现有的属性属性,或者我是否需要编写自己的属性?

void Main()
{
    string json1 = @"{ Foo: ""foo1"", Bar: ""bar1"" }";
    string json2 = @"{ Foo: ""foo2"", Bar: null }";
    string json3 = @"{ Foo: ""foo3"", Bar: """" }";

    var model1 = JObject.Parse(json1);
    var model2 = JObject.Parse(json2);
    model1.Merge(model2);
    model1.Dump();

    model1 = JObject.Parse(json1);
    model2 = JObject.Parse(json3);
    model1.Merge(model2);
    model1.Dump();
}

public class Model
{
    [JsonProperty("foo")]
    public string Foo { get ; set; }

    [JsonProperty("bar", NullValueHandling = NullValueHandling.Ignore)]
    public string Bar { get ; set; }

}

Output (1): Model.Bar = "bar1" 
Output (2): Model.Bar = "";
Desired output of (2): Model.Bar = "bar1"

编辑:好的,我意识到属性无法应用,因为我只需要将原始json字符串作为输入。这主要是因为我的类具有默认值的属性。合并具有空值的类将触发默认值并最终覆盖原始值,这是我不想要的。我需要能够获取类的部分json表示并更新原始。对不起,如果从一开始就不清楚。我会更新我最后做的答案。

2 个答案:

答案 0 :(得分:1)

您可以使用以下扩展方法从要合并的JObject中删除包含空字符串值的属性:

public static class JsonExtensions
{
    public static void RemovePropertiesByValue(this JToken root, Predicate<JValue> filter)
    {
        var nulls = root.DescendantsAndSelf().OfType<JValue>().Where(v => v.Parent is JProperty && filter(v)).ToList();
        foreach (var value in nulls)
        {
            var parent = (JProperty)value.Parent;
            parent.Remove();
        }
    }

    public static IEnumerable<JToken> DescendantsAndSelf(this JToken node)
    {
        if (node == null)
            return Enumerable.Empty<JToken>();
        var container = node as JContainer;
        if (container != null)
            return container.DescendantsAndSelf();
        else
            return new [] { node };
    }
}

然后使用它:

        model2.RemovePropertiesByValue(v => v.Type == JTokenType.String && string.IsNullOrEmpty((string)v.Value));

请注意,这不会从数组中删除空字符串,因为这会弄乱数组索引,从而导致合并。你还需要吗?

答案 1 :(得分:0)

我操纵了JObject字典键来按摩特定的条目。我觉得很脏,但它确实有效。我无法想到一个好的&#34;这样做的方法。

model1 = JObject.Parse(json1);
model2 = JObject.Parse(json3);
IDictionary<string, JToken> dictionary = model2;
dictionary["Bar"] = string.IsNullOrEmpty((string)dictionary["Bar"])
            ? null
            : dictionary["Bar"];
model1.Merge(model2);