internal static bool TryResolveAsRootError(JsonReader reader, Type objectType, JsonSerializer serializer, out IEnumerable <IError> obj) { var serializationData = SerializationData.GetSerializationData(reader); //if we already have a root object then we dont need to resolve the root object if (serializationData.HasProcessedDocumentRoot) { obj = null; return(false); } //determine the error class type. The type passed in could be an array or an object //so we need to determine the error type for both Type errorElementType; if (!ListUtil.IsList(objectType, out errorElementType)) { errorElementType = objectType; } //we do not have a root object, so this is probably the entry point, so we will resolve //a document root and return the data object var documentRootType = typeof(MinimalDocumentRoot <,>).MakeGenericType(typeof(object), errorElementType); var objContract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(documentRootType); var dataProp = objContract.Properties.GetClosestMatchProperty("errors"); var root = serializer.Deserialize(reader, documentRootType); obj = (IEnumerable <IError>)dataProp.ValueProvider.GetValue(root); return(true); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { object list; if (DocumentRootConverter.TryResolveAsRootData(reader, objectType, serializer, out list)) { return(list); } //read into the 'Data' path var preDataPath = ReaderUtil.ReadUntilStart(reader, DataPathRegex); //we should be dealing with list types, but we also want the element type Type elementType; if (!ListUtil.IsList(objectType, out elementType)) { throw new ArgumentException($"{typeof(ResourceObjectListConverter)} can only read json lists", nameof(objectType)); } var itemsIterator = ReaderUtil.IterateList(reader).Select(x => serializer.Deserialize(reader, elementType)); list = ListUtil.CreateList(objectType, itemsIterator); //read out of the 'Data' path ReaderUtil.ReadUntilEnd(reader, preDataPath); return(list); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //we may be starting the deserialization here, if thats the case we need to resolve this object as the root IEnumerable <IError> errors; if (DocumentRootConverter.TryResolveAsRootError(reader, objectType, serializer, out errors)) { return(ListUtil.CreateList(objectType, errors)); } Type elementType; ListUtil.IsList(objectType, out elementType); return(ListUtil.CreateList(objectType, ReaderUtil.IterateList(reader) .Select(x => serializer.Deserialize(reader, elementType)))); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //we may be starting the deserialization here, if thats the case we need to resolve this object as the root var serializationData = SerializationData.GetSerializationData(reader); if (!serializationData.HasProcessedDocumentRoot) { var errors = DocumentRootConverter.ResolveAsRootError(reader, objectType, serializer); return(ListUtil.CreateList(objectType, errors)); } Type elementType; ListUtil.IsList(objectType, out elementType); return(ListUtil.CreateList(objectType, ReaderUtil.IterateList(reader) .Select(x => serializer.Deserialize(reader, elementType)))); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var serializationData = SerializationData.GetSerializationData(reader); if (!serializationData.HasProcessedDocumentRoot) { return(DocumentRootConverter.ResolveAsRootData(reader, objectType, serializer)); } //we should be dealing with list types, but we also want the element type if (!ListUtil.IsList(objectType, out Type elementType)) { throw new ArgumentException($"{typeof(ResourceObjectListConverter)} can only read json lists", nameof(objectType)); } var itemsIterator = ReaderUtil.IterateList(reader).Select(x => serializer.Deserialize(reader, elementType)); var list = ListUtil.CreateList(objectType, itemsIterator); return(list); }
internal static IEnumerable <IError> ResolveAsRootError(JsonReader reader, Type objectType, JsonSerializer serializer) { //determine the error class type. The type passed in could be an array or an object //so we need to determine the error type for both Type errorElementType; if (!ListUtil.IsList(objectType, out errorElementType)) { errorElementType = objectType; } //we do not have a root object, so this is probably the entry point, so we will resolve //a document root and return the data object var documentRootType = typeof(MinimalDocumentRoot <,>).MakeGenericType(typeof(object), errorElementType); var objContract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(documentRootType); var dataProp = objContract.Properties.GetClosestMatchProperty("errors"); var root = serializer.Deserialize(reader, documentRootType); return((IEnumerable <IError>)dataProp.ValueProvider.GetValue(root)); }
public static bool CanConvertStatic(Type objectType) { Type elementType; return(ListUtil.IsList(objectType, out elementType) && ErrorConverter.CanConvertStatic(elementType)); }
private void WriteResourceJson(JsonWriter writer, object value, JsonSerializer serializer) { var resolver = (serializer.ReferenceResolver as IncludedReferenceResolver); var currentIndex = resolver.RefList.Count; var valueType = value.GetType(); //Serialize object var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(valueType); writer.WriteStartObject(); //will capture id and type as we go through object id = null; object type = null; //Handle link var linkProps = valueType.GetProperties().Where(p => p.GetCustomAttributes(typeof(ResourceAttribute), false).Count() != 0).ToList(); //A resource object MUST contain at least the following top-level members: type var typeProp = contract.Properties.GetClosestMatchProperty("type"); type = GenerateDefaultTypeName(valueType); if (typeProp == null) { writer.WritePropertyName("type"); serializer.Serialize(writer, type); } List <JsonWriterCapture> attributes = new List <JsonWriterCapture>(); List <JsonWriterCapture> relationships = new List <JsonWriterCapture>(); foreach (var prop in contract.Properties.Where(x => !x.Ignored)) { var propValue = prop.ValueProvider.GetValue(value); if (propValue == null && (prop.NullValueHandling ?? serializer.NullValueHandling) == NullValueHandling.Ignore) { continue; } switch (prop.PropertyName) { //In addition, a resource object MAY contain any of these top - level members: links, meta, attributes, relationships case PropertyNames.Id: //Id is optional on base objects case PropertyNames.Tid: // id = propValue; writer.WritePropertyName(prop.PropertyName); serializer.Serialize(writer, id); break; case PropertyNames.Meta: writer.WritePropertyName(prop.PropertyName); serializer.Serialize(writer, propValue); break; case PropertyNames.Type: writer.WritePropertyName(PropertyNames.Type); type = typeProp?.ValueProvider?.GetValue(value) ?? GenerateDefaultTypeName(valueType); serializer.Serialize(writer, type); break; default: var resAttr = linkProps?.Where(l => l.Name.ToLower() == prop.PropertyName.ToLower()).SingleOrDefault(); //we do not know if it is an Attribute or a Relationship //so we will send out a probe to determine which one it is var probe = new AttributeOrRelationshipProbe(); probe.WritePropertyName(prop.PropertyName); serializer.Serialize(probe, propValue); //handle relationship links start if (probe.PropertyType == AttributeOrRelationshipProbe.Type.Relationship) { ResourceAttribute link = null; if (resAttr != null) { link = resAttr.GetCustomAttributes(typeof(ResourceAttribute), false)[0] as ResourceAttribute; if (link.Links != null && link.Links.Count > 0) { //probe.WriteStartObject(); var act = probe.GetActions(); //001:remove last entry and add links act.RemoveAt(act.Count - 1); WriterUtil.GenerateResourceLinks(serializer, probe, value, link, type.ToString(), prop.PropertyName, propValue); //additional end object since it is removed to add links in 001 section probe.AddEndObject(); } if (!link.IsResource) { probe.PropertyType = AttributeOrRelationshipProbe.Type.Attribute; } } //Handle Includes if (resolver.Includes != null && resolver.Includes.Count() > 0) { if (ListUtil.IsList(propValue.GetType())) { var enumerable = propValue as IEnumerable <object> ?? Enumerable.Empty <object>(); var include_name = ((link != null && !string.IsNullOrEmpty(link.IncludeName)) ? link.IncludeName : prop.PropertyName); if (enumerable.Count() > 0 && resolver.Includes.Contains(include_name.ToLower())) { foreach (var valueElement in enumerable) { var include_id = valueElement.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Id).FirstOrDefault()?.GetValue(valueElement); var include_type = valueElement.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Type).FirstOrDefault()?.GetValue(valueElement); if (include_type == null) { include_type = valueElement.GetType().Name.ToLower(); } if (include_id != null && include_type != null) { var refer = IncludedReferenceResolver.GetReferenceValue(include_id.ToString(), include_type.ToString()); resolver.ResourceToInclude.Add(refer); serializer.ReferenceResolver.AddReference(null, refer, valueElement); } } } } else { var include_id = propValue.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Id).FirstOrDefault()?.GetValue(propValue); var include_type = propValue.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Type).FirstOrDefault()?.GetValue(propValue); if (include_type == null) { include_type = propValue.GetType().Name.ToLower(); } if (include_id != null && include_type != null) { var include_name = ((link != null && !string.IsNullOrEmpty(link.IncludeName)) ? link.IncludeName : prop.PropertyName); if (resolver.Includes != null && resolver.Includes.Contains(include_name.ToLower())) { var refer = IncludedReferenceResolver.GetReferenceValue(include_id.ToString(), include_type.ToString()); resolver.ResourceToInclude.Add(refer); serializer.ReferenceResolver.AddReference(null, refer, propValue); } } } } } //handle relationship links end (probe.PropertyType == AttributeOrRelationshipProbe.Type.Attribute ? attributes : relationships).Add(probe); break; } } //add reference to this type, so others can reference it var referenceValue = IncludedReferenceResolver.GetReferenceValue(id?.ToString(), type?.ToString()); serializer.ReferenceResolver.AddReference(null, referenceValue, value); resolver?.RenderedReferences?.Add(referenceValue); //set parent reference for generating link parameters for (int i = currentIndex; i < resolver.RefList.Count; i++) { if (resolver.RefList[i].Reference != referenceValue) { resolver.RefList[i].ParentReference = referenceValue; } } //output our attibutes in an attribute tag if (attributes.Count > 0) { writer.WritePropertyName(PropertyNames.Attributes); writer.WriteStartObject(); foreach (var attribute in attributes) { attribute.ApplyCaptured(writer); } writer.WriteEndObject(); } //output our relationships in a relationship tag if (relationships.Count > 0) { writer.WritePropertyName(PropertyNames.Relationships); writer.WriteStartObject(); foreach (var relationship in relationships) { relationship.ApplyCaptured(writer); } writer.WriteEndObject(); } //Links var res = ((value.GetType().GetCustomAttributes(typeof(ResourceAttribute))).SingleOrDefault() as ResourceAttribute); WriterUtil.GenerateResourceLinks(serializer, writer, value, res, type.ToString()); writer.WriteEndObject(); }
public static bool CanConvertStatic(Type objectType, JsonConverter elementConvertor) { return(ListUtil.IsList(objectType, out Type elementType) && elementConvertor.CanConvert(elementType)); }
public override bool CanConvert(Type objectType) { Type elementType; return(ListUtil.IsList(objectType, out elementType) && ResourceObjectConverter.CanConvert(elementType)); }
private bool IsArrayOf(Type type, Func <Type, bool> elementTypeCheck) { return(ListUtil.IsList(type, out Type elementType) && elementTypeCheck(elementType)); }