Пользовательский импровизированный объект для десериализации json.net
Я поигрался с импровизированным интерфейсом над заданием и столкнулся со следующей проблемой
https://code.google.com/p/impromptu-interface/issues/detail?id=17
Проблема помечена как "Не будет исправлено", и в комментариях автор говорит, что ее можно исправить, внедрив собственный импровизированный объект.
У кого-нибудь есть образец такой реализации? Или знаете другое решение этой проблемы?
1 ответ
Так что проблема в том, что JArray
имеет GetEnumerator(), определенный как только интерфейс, который делает метод больше не вызываемым по утке, вызываемым DLR. Так что ниже я переопределил trygetmember
проверить, является ли результат JArray
и преобразовать его в JEnumerable
который реализует GetEnumerator() в вызываемом способе dlr.
public class NonRecursiveJArrayConversionDictionary : ImpromptuDictionary{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if(base.TryGetMember(binder, out result)){
if(result is JArray){
result = ((JArray)result).AsJEnumerable();
}
return true;
}
result = null;
return false;
}
}
Однако это будет работать только для структур json, которые не имеют массивов более чем на одно свойство. Вы должны либо изменить вышеприведенное, чтобы рекурсивно проверять каждый раз, когда что-либо возвращается, возможно, через прокси, либо изменять индексатор словаря. set
чтобы проверить и конвертировать при десериализации вместо этого.
Обновление: Json.net verion> = 5.0.4.16101 и ImpromptuInterface >= 6.1.4 будут работать из коробки.
void Main()
{
ICustomer customer = Impromptu.ActLike(JObject.Parse(@"
{
Id: 1,
Name:'Test',
Location:'Somewhere',
Employees: [
{ Id:1, EmployerId:39421, Name:'Joe' },
{ Id:2, EmployerId:39421, Name:'Jane' },
]
}
"));
foreach(var employee in customer.Employees){
employee.Id.Dump();
employee.Name.Dump();
}
}
public interface ICustomer
{
int Id { get; set; }
string Name { get; set; }
string Location { get; set; }
IList<IEmployee> Employees { get; }
}
public interface IEmployee
{
int Id { get; set; }
int EmployerId { get; set; }
string Name { get; set; }
}