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

C# 如果JSON.NET中的值为null或空白,则阻止序列化,c#,json.net,C#,Json.net,我有一个对象,它需要以这样一种方式序列化:null和“whitespace”(空或仅空格)值都不序列化。我不控制对象本身,因此无法设置属性,但我知道所有属性都是字符串。将NullValueHandling设置为Ignore显然只能让我找到部分解决方案 “似乎”(据我所知)我需要做的是创建一个自定义的DefaultContractResolver,但我还没有找到一个有效的解决方案。以下是一些失败的尝试,仅供参考,它们不会引发异常,但对序列化也没有明显影响: public class NoNullW

我有一个对象,它需要以这样一种方式序列化:null和“whitespace”(空或仅空格)值都不序列化。我不控制对象本身,因此无法设置属性,但我知道所有属性都是字符串。将
NullValueHandling
设置为Ignore显然只能让我找到部分解决方案

“似乎”(据我所知)我需要做的是创建一个自定义的
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();
});
也许我是在倒退,但我很欣赏人们的见解。我已经解决了这个问题,使用扩展方法/反射来迭代对象的属性,如果是“nullorwhitespace”,则将值设置为null,然后使用标准的
NullValueHandling
,但我希望我能找到一种在序列化中配置所有这些的方法。

这似乎有效:

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"}

这里有几次失败的尝试,仅供参考,它们不会抛出异常“-
catch{return true;}
会抑制无效的强制转换异常。@stuartd是的,这是故意的;但我问题中的注释在这种情况下是多余的-抱歉。这确实有效。我很接近,但不够接近;)谢谢!