如果值为null或JSON.NET中的空格,则阻止序列化

时间:2018-06-13 14:55:35

标签: c# json.net

我有一个对象需要以这样的方式序列化:null和" whitespace" (空或只是空格)值未序列化。我无法控制对象本身,因此无法设置属性,但我知道所有属性都是字符串。将NullValueHandling设置为忽略显然只会让我成为解决方案的一部分。

它"似乎" (据我所知),我需要做的就是创建一个自定义DefaultContractResolver,但我还没有找到一个有效的解决方案。以下是一些失败的尝试,作为参考,没有例外,但对序列化没有明显影响:

public class NoNullWhiteSpaceResolver : DefaultContractResolver
{
    public static readonly NoNullWhiteSpaceResolver Instance = new NoNullWhiteSpaceResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        /* this doesn't work either
        if (property.ValueProvider.GetValue(member) == null ||
            (property.PropertyType == typeof(string) &&
            string.IsNullOrWhiteSpace((string)property.ValueProvider.GetValue(member))))
        {
            property.ShouldSerialize = i => false;
        }*/

        if (property.PropertyType == typeof(string))
        {
            property.ShouldSerialize =
                instance =>
                {
                    try
                    {
                        string s = (string) instance;
                        bool shouldSkip = string.IsNullOrWhiteSpace(s);
                        return !string.IsNullOrWhiteSpace(s);
                    }
                    catch
                    {
                        return true;
                    }
                };
        }

        return property;
    }
}

我通过

实施解析器
string str = JsonConvert.SerializeObject(obj, new JsonSerializerSettings
{
    Formatting = Formatting.None;
    ContractResolver = new NoNullWhiteSpaceResolver();
});

也许我正在向后看,但我很欣赏人们的见解。我通过使用扩展方法/反射迭代对象的属性并将值设置为null(如果它是" nullorwhitespace"然后使用标准NullValueHandling,但我希望我能找到一种方法来配置序列化中的所有这些。

1 个答案:

答案 0 :(得分:2)

这似乎有效:

public class NoNullWhiteSpaceResolver : DefaultContractResolver {
    public static readonly NoNullWhiteSpaceResolver Instance = new NoNullWhiteSpaceResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        if (property.PropertyType == typeof(string)) {
            property.ShouldSerialize =
                instance => {
                    try {
                        var rawValue = property.ValueProvider.GetValue(instance);
                        if (rawValue == null) {
                            return false;
                        }

                        string stringValue = property.ValueProvider.GetValue(instance).ToString();
                        return !string.IsNullOrWhiteSpace(stringValue);
                    }
                    catch {
                        return true;
                    }
                };
        }

        return property;
    }
}

使用此测试类:

public class TestClass {
    public string WhiteSpace => "      ";
    public string Null = null;
    public string Empty = string.Empty;
    public string Value = "value";
}

这是输出:

{"Value":"value"}