在编写API时,我们遇到了过滤掉请求用户无权访问的模型属性的要求。
使用Json.Net ContractResolver,我们能够在很大程度上解决这个问题。
public class ConverterContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
{
//filter the properties and return back the final list
}
}
然而,在参考属性急切加载的情况下,ContactResolver似乎无效。 例如,对于以下类:
public class Contact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string AccountId { get; set; }
public Account Account { get; set; }
}
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public string Website { get; set; }
public string BillingAddress { get; set; }
}
当查询联系人时,可能急切地加载帐户记录,当序列化为JSON时,ContractResolver将仅在联系人字段而不是帐户字段上应用过滤器。
Contact data = new Contact {
FirstName = "John",
LastName = "Duo",
AccountId = 123,
Account = new Account { Id=123, Name="My Company", Website="www.mycompany.com" }
};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(data,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings {
ContractResolver= new ConverterContractResolver()
});
有没有办法让Json.net为参考属性调用相同的合约解析器?
答案 0 :(得分:2)
最终我发现在我的模型中每个引用的对象都会调用ContractResolver。 这部分是好的,但有点问题,因为它只传递被解析的对象的类型为JSON,没有关于深度或找到对象的位置的信息。
public class ConverterContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type,
Newtonsoft.Json.MemberSerialization memberSerialization)
{
//filter the properties and return back the final list
}
}
通过添加一个计数器来调用CreateProperties的次数,我设法识别哪个调用是针对主模型的,哪个后续调用是针对引用的对象。
这部分解决了我的问题,现在相同的ContractorResolver将过滤应用于模型中的所有引用对象。