在JSON序列化中替换敏感数据值

11

我有一些对象,想要将它们序列化为 JSON。然而,其中一些对象具有通过属性被视为“SensitiveData”的属性。

[SensitiveDataAttribute]
public string SomeSensitiveProperty {get; set;}

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

目前,我正在重写序列化器上的“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;
        }
    }
}

当我进行序列化时,我会使用该解析器作为序列化器的设置:

var settings = new JsonSerializerSettings() { ContractResolver = new SensitiveDataResolver() };
var requestString = JsonConvert.SerializeObject(someObject, settings);

我的问题是,我不想将属性从序列化中排除。我想要序列化它们,但默认值为“SensitiveData”。

是否有一种方法可以使用属性实现这个目的?


这个回答对您有帮助吗?在自定义JSON.net合同解析程序中覆盖属性值 - Liam
4个回答

11

如果成员有属性,你可以通过覆盖属性值的方式来代替使用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;
}

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

1

为敏感数据属性实现IValueProvider接口,并将其用于PropertyValueProvider

public class SensitiveDataProvider : IValueProvider
{
    readonly string sesitiveDatatag = "Sensitive Data";
    public object GetValue(object target)
    {
        return sesitiveDatatag;
    }

    public void SetValue(object target, object value)
    {
        target = sesitiveDatatag;
    }
}

现在你的 DefaultContractResolver 会是这样的:
    public class SensitiveDataResolver : DefaultContractResolver
    {
        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 SensitiveDataProvider();
                }
            }

            return property;
        }
    }

0

你可以直接覆盖属性值,而不是设置 property.ShouldSerialize。

public class SensitiveDataResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        if (this.IsSensitiveProperty(member))
        {
            ((PropertyInfo)member).SetValue(member, "SensitiveData", null);
        }

        var property = base.CreateProperty(member, memberSerialization);
        return property;
    }

    private bool IsSensitiveProperty(MemberInfo member)
    {
        if (member is PropertyInfo)
        {
            var prop = (PropertyInfo) member;
            var isSensitiveData = Attribute.IsDefined(prop, typeof (SensitiveDataAttribute));
            return isSensitiveData;
        }
        return false;
    }
}

-1

你可以在你的合同解析器中使用反射来实现这个。

PropertyInfo[] props = typeof(instanceOfMyClass).GetProperties();
foreach (PropertyInfo prop in props)
{
     object[] attrs = prop.GetCustomAttributes(true);
     foreach (object attr in attrs)
     {
           var sensitive = attr as SensitiveDataAttribute;
           if (sensitive != null)
           {
               //add the default value to your property here
              prop.SetValue(instanceOfMyClass, "Default Value", null);
          }
     }
}

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