Newtonsoft JSON - 无需添加[JsonIgnore]即可忽略属性的方法

时间:2017-07-10 11:14:46

标签: c#

这看似愚蠢,但这是我能说出来的唯一方法。

我要做的是序列化一个对象及其数据。该对象继承了一个大型BaseObject类。我不希望继承对象中的任何信息出现在Json对象中,但我无法访问或更改BaseObject类

该类几乎用于所有对象,有时我将Json序列化需要许多属性,因此向类中添加[JsonIgnore]将无法使其正常工作。

我想知道是否有其他方法可以使用JsonSerializerSettings或任何其他方式来执行此操作。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:4)

是的,这可以使用自定义合约解析程序。

这样的事情:

public class BaseClass
{
    public string BaseClassProperty { get; set; }
}

public class ChildClass: BaseClass
{
    public string ChildClassProperty { get; set; }
}

public class CustomContractResolver : DefaultContractResolver
{

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        var propsToIgnore = typeof(BaseClass).GetProperties().Select(p => p.Name).ToList();

        properties =
            properties.Where(p => !propsToIgnore.Contains( p.PropertyName) ).ToList();

        return properties;
    }
}

那么这个:

var test = new ChildClass { BaseClassProperty = "a", ChildClassProperty = "b" };

var searialisedString = JsonConvert.SerializeObject(test, new JsonSerializerSettings
{
    ContractResolver = new CustomContractResolver()
});

Console.WriteLine(searialisedString);

产生预期的输出:

{"ChildClassProperty":"b"}

答案 1 :(得分:1)

我建议不要摆弄可能在其他地方使用的基础对象或序列化程序,并且可能产生奇怪的效果。

有一种模式可用于执行此类操作,您希望在不同区域或域之间屏蔽或聚合数据:

Data transfer object

我建议调查一下。它允许您在API上拥有一组更细粒度的模型,这些模型不会暴露您的所有代码,您甚至可以通过nuget或类似的方法使用最小依赖项的小DLL将它们公开。

表示您的代码可能看起来有点像

public static class MyObjectDtoMapper {
    public static Contract.MyDto Map(SpecificDomain.MyObject obj) {
        return new MyDto {
            OnlyPropertyWanted = obj.Property
        };
    }
}

var dtoMappedObject = MyObjectJsonDtoMapper.Map(object);
return JsonConvert.SerializeObject(dtoMappedObject);

如果您想扩展此功能,可以使用AutoMapper之类的库来提供帮助。这提供了构建这些Mapper类的框架。