1

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

这是我的界面和 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 不包含“名称”,如果它会序列化它的空名称根实体。

帮助?

4

1 回答 1

1

您可以挂钩 Json.NET 的条件属性序列化功能,以添加测试以确定给定属性在序列化之前是否已被修改:

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

样品小提琴

于 2016-12-19T07:57:34.643 回答