替换JSON序列化上的敏感数据值

JBo*_*ond 6 c# serialization json json.net

我有一些我想要序列化为JSON的对象.但是,某些对象具有通过属性被视为"SensitiveData"的属性.

[SensitiveDataAttribute]
public string SomeSensitiveProperty {get; set;}
Run Code Online (Sandbox Code Playgroud)

目前,我正在覆盖序列化程序上的'CreateProperty'方法,以便我可以根据是否具有此'SensitiveData'属性来更改是否应该序列化属性:

public class SensitiveDataResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var property = base.CreateProperty(member, memberSerialization);
            property.ShouldSerialize = instance =>
            {
                if (member is PropertyInfo)
                {
                    var prop = (PropertyInfo) member;
                    var isSensitiveData = Attribute.IsDefined(prop, typeof (SensitiveDataAttribute));
                    return !isSensitiveData;
                }
                return false;
            };
            return property;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我序列化时,我然后使用该解析器作为序列化器的设置:

var settings = new JsonSerializerSettings() { ContractResolver = new SensitiveDataResolver() };
var requestString = JsonConvert.SerializeObject(someObject, settings);
Run Code Online (Sandbox Code Playgroud)

我的问题是,我不希望从序列化中排除属性.我希望它们被序列化,但默认值为'SensitiveData'.

有没有办法使用Attributes实现这一目标?

Tom*_*ers 8

ShouldSerialize如果成员具有该属性,则可以仅覆盖属性值,而不是使用该方法.为此,您需要为IValueProvider序列化时使用的Json.NET 提供自定义.

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
    var property = base.CreateProperty(member, memberSerialization);

    if (member is PropertyInfo)
    {
        var prop = (PropertyInfo)member;
        var isSensitiveData = Attribute.IsDefined(prop, typeof (SensitiveDataAttribute));

        if (isSensitiveData)
            property.ValueProvider = new StringValueProvider("SensitiveData");
    }

    return property;
}
Run Code Online (Sandbox Code Playgroud)

StringValueProviderIValueProvider界面的自定义实现.

public class StringValueProvider : IValueProvider
{
    private readonly string _value;

    public StringValueProvider(string value)
    {
        _value = value;
    }

    public void SetValue(object target, object value)
    {
        throw new NotSupportedException();
    }

    public object GetValue(object target)
    {
        return _value;
    }
}
Run Code Online (Sandbox Code Playgroud)