So the problem is that JArray
has GetEnumerator() defined as interface-only, which makes the method no longer duck callable by the DLR. So below I've overriden the trygetmember
to check if the result is a JArray
's and convert it to a JEnumerable
that implements GetEnumerator() in a dlr invokable way.
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;
}
}
However, this will only work for json structures that don't have arrays more then one property deep. You'll either have modify the above to recursively check anytime anything is returned maybe with a proxy, or modify the dictionary indexer's set
to check and convert when deserialized instead.
Update: Json.net verion >= 5.0.4.16101 and ImpromptuInterface >= 6.1.4 will work out of the box.
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; }
}