private object ReadJsonInternal(IJsonNetReader reader, Type objectType, object existingValue, IJsonNetSerializer serializer, int depth) { // mbr - 2016-07-07 - if we get null, quit... if (reader.TokenType == JsonNetTokenShim.Null) { return(null); } string readingName = null; // walk... var dto = (IDtoBase)Activator.CreateInstance(objectType); while (true) { var didPeek = false; // what did we get? if (reader.TokenType == JsonNetTokenShim.EndObject) { break; } else if (reader.TokenType == JsonNetTokenShim.PropertyName) { readingName = (string)reader.Value; } else if (reader.TokenType == JsonNetTokenShim.String || reader.TokenType == JsonNetTokenShim.Boolean || reader.TokenType == JsonNetTokenShim.Integer || reader.TokenType == JsonNetTokenShim.Float || reader.TokenType == JsonNetTokenShim.Date || reader.TokenType == JsonNetTokenShim.Null) { // field... var field = dto.Type.GetFieldByJsonName(readingName, false); if (field != null) { // set... if (field.CanWrite) { dto[field] = reader.Value; } } else { // mbr - 2015-06-17 - we might have a property that's not mapped to a field. this will happen if we // use a DtoBase<> as a base type (e.g. "SaveOrderLineDto")... var prop = GetAdhocProperty(dto.GetType(), readingName); if (prop != null && prop.CanWrite) { var toSet = ConversionHelper.ChangeType(reader.Value, prop.PropertyType); prop.SetValue(dto, toSet); } } // reset... readingName = null; } else if (reader.TokenType == JsonNetTokenShim.StartObject) { if (!(string.IsNullOrEmpty(readingName))) { var member = dto.Type.GetMemberByJsonName(readingName, false); if (member != null) { // what is it? if (typeof(IDtoBase).IsAssignableFrom(member.ValueType)) { // read something we know... var inner = (IDtoBase)this.ReadJsonInternal(reader, member.ValueType, existingValue, serializer, depth + 1); // set... if (member is DtoLink) { dto.SetLink((DtoLink)member, inner); } else { throw new NotSupportedException(string.Format("Cannot handle '{0}'.", member.GetType())); } } else { // read it generally... //var inner = serializer.; //var prop = this.GetAdhocProperty(member.ValueType, member.JsonName); //if (prop != null && prop.CanWrite) // prop.SetValue(dto, inner); throw new NotImplementedException("This operation has not been implemented."); } } else { // drain here... while (true) { if (!(reader.Read())) { throw new InvalidOperationException("End of stream encountered whilst looking for end of object. "); } // stop? if (reader.TokenType == JsonNetTokenShim.EndObject) { break; } } } } } else if (reader.TokenType == JsonNetTokenShim.StartArray) { // find the field... var field = dto.Type.GetFieldByJsonName(readingName, false); if (field != null) { // go next... if (!(reader.Read())) { throw new InvalidOperationException("End of stream encountered whilst stepping into array."); } // get the object type... Type subtype = null; if (typeof(IEnumerable).IsAssignableFrom(field.DtoProperty.PropertyType)) { if (field.DtoProperty.PropertyType.GenericTypeArguments.Length == 1) { subtype = field.DtoProperty.PropertyType.GenericTypeArguments[0]; } else { throw new NotSupportedException(string.Format("A parameter of set length '{0}' is invalid.", field.DtoProperty.PropertyType.GenericTypeArguments.Length)); } } else { throw new NotSupportedException(string.Format("Cannot handle '{0}'.", field.DtoProperty.PropertyType)); } // read... var readingList = (IList)Activator.CreateInstance(field.DtoProperty.PropertyType); while (true) { var inner = this.ReadJsonInternal(reader, subtype, existingValue, serializer, depth + 1); if (inner == null) { throw new InvalidOperationException("'inner' is null."); } // add... readingList.Add(inner); // now what? if (!(reader.Read())) { throw new InvalidOperationException("End of stream encountered whilst peaking array end."); } // what did we get? if (reader.TokenType == JsonNetTokenShim.StartObject) { } else if (reader.TokenType == JsonNetTokenShim.EndArray) { // set the result... dto[field] = readingList; // go back to the top of the loop... didPeek = true; break; } else { throw new NotSupportedException(string.Format("Cannot handle '{0}'.", reader.TokenType)); } } } else { // flush... while (true) { if (reader.TokenType == JsonNetTokenShim.EndArray) { break; } if (!(reader.Read())) { throw new InvalidOperationException("End of stream encountered whilst looking for end of array."); } } } } if (!(didPeek)) { if (!(reader.Read())) { break; } } } // return... return(dto); }
public object ReadJson(IJsonNetReader reader, Type objectType, object existingValue, IJsonNetSerializer serializer) { return(this.ReadJsonInternal(reader, objectType, existingValue, serializer, 0)); }