这是一个有趣的问题。我的回答大量借鉴了您提供的链接,但会检查定义您的“高级内容”(用户付费的东西)的自定义属性:
像你的链接一样,我定义了一个类Foo,它将被序列化。它包含一个子对象PremiumStuff,其中包含只有在用户付费时才应该序列化的东西。我已经用自定义属性PremiumContent 标记了这个子对象,该属性也在这段代码 sn-p 中定义。然后我使用了一个从DefaultContractResolver 继承的自定义类,就像链接一样,但是在这个实现中,我正在检查我们的自定义属性的每个属性,并且只有在属性标记为时才在if 块中运行代码PremiumContent。此条件代码检查名为AllowPremiumContent 的静态布尔值,以查看我们是否允许对高级内容进行序列化。如果不允许,那么我们将 Ignore 标志设置为 true:
class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string AlternateName { get; set; }
[PremiumContent]
public PremiumStuff ExtraContent { get; set; }
}
class PremiumStuff
{
public string ExtraInfo { get; set; }
public string SecretInfo { get; set; }
}
class IncludePremiumContentAttributesResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (var prop in props)
{
if (Attribute.IsDefined(type.GetProperty(prop.PropertyName), typeof(PremiumContent)))
{
//if the attribute is marked with [PremiumContent]
if (PremiumContentRights.AllowPremiumContent == false)
{
prop.Ignored = true; // Ignore this if PremiumContentRights.AllowPremiumContent is set to false
}
}
}
return props;
}
}
[System.AttributeUsage(System.AttributeTargets.All)]
public class PremiumContent : Attribute
{
}
public static class PremiumContentRights
{
public static bool AllowPremiumContent = true;
}
现在,让我们实现它,看看我们得到了什么。这是我的测试代码:
PremiumContentRights.AllowPremiumContent = true;
Foo foo = new Foo()
{
Id = 1,
Name = "Hello",
AlternateName = "World",
ExtraContent = new PremiumStuff()
{
ExtraInfo = "For premium",
SecretInfo = "users only."
}
};
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new IncludePremiumContentAttributesResolver();
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(foo, settings);
Debug.WriteLine(json);
在第一行,PremiumContentRights.AllowPremiumContent 设置为 true,输出如下:
{
"Id": 1,
"Name": "Hello",
"ExtraContent": {
"ExtraInfo": "For premium",
"SecretInfo": "users only."
}
}
如果我们将AllowPremiumContent 设置为False 并再次运行代码,输出如下:
{
"Id": 1,
"Name": "Hello"
}
如您所见,ExtraContent 属性被包含或忽略取决于AllowPremiumContent 变量的状态。