使用Json.net只序列化特定属性。

17
Json.net有没有指定只序列化想要的属性的方法?或者根据绑定标志(例如仅声明)序列化某些属性?目前我正在使用JObject.FromObject(MainObj.SubObj);获取SubObj的所有属性,它是一个遵循ISubObject接口的类的实例:
public interface ISubObject
{

}

public class ParentSubObject : ISubObject
{
    public string A { get; set; }
}


public class SubObjectWithOnlyDeclared : ParentSubObject
{
    [JsonInclude] // This is fake, but what I am wishing existed
    public string B { get; set; }

    [JsonInclude] // This is fake, but what I am wishing existed
    public string C { get; set; }
}

public class NormalSubObject: ParentSubObject
{
    public string B { get; set; }
}
如果 MainObj.SubObj是一个NormalSubObject,它会序列化 A 和 B,但如果它是SubObjectWithOnlyDeclared,它只会序列化 B 和 C,并忽略父属性。

2
[JsonIgnore] ? - Eser
2
看看这篇关于条件序列化的文章,我觉得很有用。https://www.geekytidbits.com/conditional-serialization-with-json-net/ - Rich
1
请返回翻译文本:也可以在这里查看:https://dev59.com/J2kw5IYBdhLWcg3wDWTL#59227350 - Alex from Jitbit
4个回答

51

与其像另一个答案中建议的那样,在每个您不想序列化的属性上使用[JsonIgnore],不如只想指定要序列化的属性,您可以使用[JsonObject(MemberSerialization.OptIn)][JsonProperty]属性来实现,就像这样:

using Newtonsoft.Json;
...
[JsonObject(MemberSerialization.OptIn)]
public class Class1
{
    [JsonProperty]
    public string Property1 { set; get; }
    public string Property2 { set; get; }
}

只有Property1会被序列化。


3
这应该是被选中的答案。 - JKennedy

17

你可以编写类似以下的自定义ContractResolver

public class IgnoreParentPropertiesResolver : DefaultContractResolver
{
    bool IgnoreBase = false;
    public IgnoreParentPropertiesResolver(bool ignoreBase)
    {
        IgnoreBase = ignoreBase;
    }
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var allProps = base.CreateProperties(type, memberSerialization);
        if (!IgnoreBase) return allProps;

        //Choose the properties you want to serialize/deserialize
        var props = type.GetProperties(~BindingFlags.FlattenHierarchy); 

        return allProps.Where(p => props.Any(a => a.Name == p.PropertyName)).ToList();
    }
}
现在你可以将它用于你的序列化过程中,例如:
var settings = new JsonSerializerSettings() { 
                      ContractResolver = new IgnoreParentPropertiesResolver(true) 
               };
var json1 = JsonConvert.SerializeObject(new SubObjectWithOnlyDeclared(),settings );

谢谢,这正是我在寻找的。 - papfan

3

不确定为什么@Eser选择将答案作为评论写在您的问题中,而不是作为实际答案...无论如何,他们是正确的。

[JsonIgnore]属性应用于您想要忽略的任何属性。


2
这并不是一个可接受的答案,因为我需要有条件地忽略 public string A { get; set; },因为在某种情况下我不想要它被忽略,在另一种情况下我则需要。 - CuriousDeveloper

3
如果您的对象上有一个null或默认值的属性,您可以让json.net忽略它并且不进行序列化处理,方法如下:
var settings = new JsonSerializerSettings 
{
    DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore
};

JsonConvert.SerializeObject(myObject, settings);

编辑:

或者全局默认设置,只需执行一次以下操作:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings 
{
    DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore
};

非常感谢,这正是我在寻找的。 - sabsab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接