继承DefaultContractResolver并以不同方式对待引用的实体 [英] Inheriting DefaultContractResolver and treating referenced entities differently

查看:638
本文介绍了继承DefaultContractResolver并以不同方式对待引用的实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to serialize only changed properties. I was managed to do it for the root type, but it contains references to other objects to be serialized (that might even be of the same type).

这是我的界面和ContractResolver:

This is my interface and 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属性将具有接收到值的属性名称的列表.

The property PropertiesToSerialize will have a list of property names that received a value.

这是我的序列化方式:

        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;

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

And this is an example of a type I can serialize:

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不包含名称",如果可以,则将序列化名称.根实体的空名称.

As you can understand, If I only set a category for my root type which has a name, it won't serialize the name because the root PropertiesToSerialize doesn't contain "Name", If it would of it would serialize the empty name of the root entity.

帮助?

推荐答案

您可以插入

You can hook into the conditional property serialization functionality of Json.NET to add a test to determine whether a given property has been modified before serializing it:

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

示例小提琴.

这篇关于继承DefaultContractResolver并以不同方式对待引用的实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆