继承DefaultContractResolver并以不同方式处理引用的实体

时间:2013-05-20 20:35:37

标签: c# json json.net

我想仅序列化已更改的属性。我设法为root类型执行此操作,但它包含对要序列化的其他对象的引用(甚至可能是相同的类型)。

这是我的界面和ContractResolver:

public interface ISelectiveJsonSerialize
{
    IList<string> PropertiesToSerialize { get; }
}

public class JsonSelectiveSerializeContractResolver : DefaultContractResolver
{
    private readonly IList<string> _propertiesToSerialize;

    public JsonSelectiveSerializeContractResolver(IList<string> propertiesToSerialize)
    {
        _propertiesToSerialize = propertiesToSerialize;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        return base.CreateProperties(type, memberSerialization).Where(p => _propertiesToSerialize.Contains(p.PropertyName)).ToList();
    }
}

属性PropertiesToSerialize将包含一个接收值的属性名称列表。

这是我序列化的方式:

        string result = "";
        if (val is ISelectiveJsonSerialize)
        {
            // Don't serialize all properties
            var resolver = new JsonSelectiveSerializeContractResolver(((ISelectiveJsonSerialize)val).PropertiesToSerialize);
            var settings = new JsonSerializerSettings { ContractResolver = resolver };
            result = JsonConvert.SerializeObject(val, Formatting.None, settings);
        }
        else
        {
            // Default serialization
            result = JsonConvert.SerializeObject(val);
        }

        return result;

这是我可以序列化的类型的示例:

public class Category : BaseType
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            PropertiesToSerialize.Add("Name");
        }
    }

    private Category _category;
    public Category Category
    {
        get { return _category; }
        set
        {
            _category = value;
            PropertiesToSerialize.Add("Category");
        }
    }
}

正如您所理解的,如果我只为我的根类型设置了一个具有名称的类别,它将不会序列化该名称,因为根PropertiesToSerialize不包含“Name”,如果它将序列化根实体的空名称。

帮助?

1 个答案:

答案 0 :(得分:1)

您可以使用Json.NET的conditional property serialization功能来添加测试,以确定在序列化之前是否修改了给定属性:

public class JsonSelectiveSerializeContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        var shouldSerialize = property.ShouldSerialize;
        var name = property.PropertyName;
        property.ShouldSerialize = (o) =>
        {
            var selectiveSerialize = o as ISelectiveJsonSerialize;
            if (selectiveSerialize != null)
            {
                if (!selectiveSerialize.PropertiesToSerialize.Contains(name))
                    return false;
            }
            return shouldSerialize == null || shouldSerialize(o);
        };

        return property;
    }
}

示例fiddle