Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Newtonsoft.Json合并对象时,如何忽略空字符串值?_C#_Json_Serialization_Json.net - Fatal编程技术网

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

C# 使用Newtonsoft.Json合并对象时,如何忽略空字符串值?,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有一个在C#中定义为类的数据模型。我需要使用JObject.merge合并两个对象,但是对于一个特定属性,我需要忽略第二个对象中的空字符串值,类似于忽略空值。是否存在此属性的现有属性,或者是否需要编写自己的属性 void Main() { string json1 = @"{ Foo: ""foo1"", Bar: ""bar1"" }"; string json2 = @"{ Foo: ""foo2"", Bar: null }"; string json3 = @"

我有一个在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表示,并更新原始的json表示。抱歉,如果一开始还不清楚的话。我将更新我最后的答案。

您可以使用以下扩展方法从要合并的
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 };
    }
}

注意,这不会从数组中删除空字符串,因为这会打乱数组索引,从而导致合并。您也需要它吗?

我操作了JObject字典键来按摩特定条目。我觉得很脏,但它管用。我想不出一个“好”的方法来做这件事

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);
model1=JObject.Parse(json1);
model2=JObject.Parse(json3);
IDictionary dictionary=model2;
dictionary[“Bar”]=string.IsNullOrEmpty((string)dictionary[“Bar”])
? 无效的
:字典[“Bar”];
模式1.合并(模式2);

我更喜欢修饰属性,而不是为单个字段创建自定义代码。@DanBailiff-代码是递归的,它清除整个
JToken
层次结构中的空字符串值。此外,此时没有要装饰的属性,您使用的是
JTokens
而不是poco。唯一的背景似乎不相关。你说得对。通过将json转换为对象,然后在发出要合并的json时使用“DefaultValueHandling.Ignore”和“DefaultValue(“”)”的序列化程序属性,我找到了一个解决方法或“正确的方法”。我不知道我是应该更新问题/解决方案还是撤回问题?@DanBailiff-如果你仍然需要帮助,我建议你问一个新问题,因为它更容易引起注意。顺便说一句,你能帮忙吗?@drzaus-已经是递归的了。但是
JValue
(以及抽象基类
JToken
)没有实现
genderantsandself()
(尽管这样做是有意义的),所以
JsonExtensions.genderantsandself()
为只返回self的非容器令牌提供了一个实现。你说的是什么“是否存在此属性的现有属性属性”?中的属性?或
JObject
本身的属性?
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);