2013-09-14 5 views
1

При написании нашего API мы сталкиваемся с требованием отфильтровать свойства модели, к которой у запрашивающего пользователя нет доступа.Использование Json.Net ContractResolver и внутренних эталонных свойств

Используя 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 вызывал тот же Контрактный резолвер для ссылочных свойств?

ответ

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 применяет фильтрацию ко всем объектам, на которые ссылаются мои модели.

+0

Что произойдет, если контакт имеет два свойства учетной записи одного и того же типа «Учетная запись», и вам нужно отфильтровывать свойства по-разному для этого двух объектов типа «Учетная запись»? –

Смежные вопросы