Пользовательский импровизированный объект для десериализации 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; }
}
Другие вопросы по тегам