/// <summary> /// Binding object with object json /// </summary> /// <param name="type">Type of object</param> /// <param name="modelToBind">Instance of object</param> /// <param name="item">Object data json representing the object</param> private void BindModel(Type type, object modelToBind, JToken item) { // Check type if (this.ReadType(item) != AttributeHandling.GetLabelProperty(type)) { throw new InvalidPropertyException("type", this.ReadType(item), AttributeHandling.GetLabelProperty(type), (!string.IsNullOrEmpty(item.Path) ? item.Path : item.First.Path)); } // Bind Id this.BindId(type, modelToBind, item); // Bind Attributes IEnumerable <JToken> attributes = this.ReadAttributes(item); if (attributes != null) { this.BindAttributes(type, modelToBind, attributes); } // Bind Relationships IEnumerable <JToken> relationships = this.ReadRelationships(item); if (relationships != null) { this.BindRelationships(type, modelToBind, relationships); } }
/// <summary> /// Add attributes, relationship and included relationship /// </summary> /// <param name="model"></param> /// <param name="type"></param> /// <param name="json"></param> private void CreateAttribute(object model, Type type, JsonApiData json, string pathRelation) { foreach (PropertyInfo prop in this.GetListProperties(type, json.type)) { object value = this.ResolveData(prop, prop.GetValue(model)); string propName = AttributeHandling.GetLabelProperty(prop); if (value != null) { Type typeValue = value.GetType(); if (Utils.IsEnum(value)) { if (Utils.HasGenericTypeSystem(typeValue)) { json.AddAttribute(propName, this.SetListData(value, this._modeExtand).Select(m => m.toJsonFormat()).ToList()); } else { this.CreateRelationship(json, propName, true, this.IsInclude(pathRelation + propName), (extand) => this.SetListData(value, extand, pathRelation + propName)); } } else if (Utils.IsTypeSystem(typeValue)) { json.AddAttribute(propName, value); } else { this.CreateRelationship(json, propName, false, this.IsInclude(pathRelation + propName), (extand) => this.SetData(value, extand, pathRelation + propName)); } } } }
/// <summary> /// Bind object property Id /// <param name="type">Type object</param> /// <param name="modelToBind">Instance object</param> /// </summary> private void BindId(Type type, object modelToBind, JToken item) { string id = this.ReadId(item); if (id == null) { return; } List <PropertyInfo> listeIdProperty = AttributeHandling.GetIdsProperties(type).Where(prop => prop.CanWrite).ToList(); if (!listeIdProperty.Any()) { throw new NotImplementedJsonApiException($"{type.Name} has not attribute id"); } if (listeIdProperty.Count == 1) { // Check constraint Id on main Model if (modelToBind == this._modelToBind) { if (this._constraintId > 0 && id != this._constraintId.ToString()) { throw new InvalidPropertyException("id", id, this._constraintId.ToString()); } if (this._isPostRequest && id != "0") { throw new InvalidPropertyException("id", id, "empty", "POST Method"); } } this.BindIdValue(listeIdProperty.First(), modelToBind, item, id); } else { string[] ids = id.Split(Constants.SEPERATOR_IDS); if (listeIdProperty.Count != ids.Length) { this._error.Create(Constants.ERROR_STATUT_JSONAPI, $"Error Format on attribute Id", "Id value is incorrect", item.ToString()); return; } foreach (PropertyInfo idProperty in listeIdProperty) { this.BindIdValue(idProperty, modelToBind, item, ids[listeIdProperty.IndexOf(idProperty)]); } } }
private object ResolveData(PropertyInfo prop, object data) { if (this._resolverData == null) { return(data); } string resolverName = AttributeHandling.GetResolverName(prop); if (resolverName == null) { return(data); } return(this._resolverData.ResolveReader(resolverName, data)); }
/// <summary> /// Create base object (id, type) /// </summary> /// <param name="model"></param> /// <param name="type"></param> /// <param name="extandData"></param> /// <returns></returns> private IJsonApiObject CreateJsonApiOject(object model, Type type, bool extandData) { IJsonApiObject returnObject = extandData ? new JsonApiData() : new JsonApiDataBase(); IEnumerable <PropertyInfo> idsProperties = AttributeHandling.GetIdsProperties(type); if (idsProperties.Any()) { returnObject.id = string.Join(Constants.SEPERATOR_IDS, idsProperties.Select(p => p.GetValue(model).ToString())); } string labelType = AttributeHandling.GetLabelProperty(type); returnObject.type = (!type.Name.Contains("AnonymousType")) ? labelType : null; return(returnObject); }
/// <summary> /// Bind object property type of object /// </summary> /// <param name="type">Type objec</param> /// <param name="modelToBind">Instance object</param> /// <param name="relationships">List object</param> private void BindRelationships(Type type, object modelToBind, IEnumerable <JToken> relationships) { foreach (JProperty attr in relationships) { PropertyInfo relationship = AttributeHandling.GetProperty(type, attr.Name); if (relationship == null) { throw new InvalidPropertyException(type, attr.Name, true); } Type typeRelationship = AttributeHandling.GetTypeProperty(relationship); object tempObj = Activator.CreateInstance(typeRelationship); if (Utils.IsEnum(tempObj)) { if (this.GetTypeJProperty(attr.First()) != "Array") { throw new InvalidPropertyException("json", attr.Name, "Array"); } //--------Cas particulier------// //Type spécifié Type sendedType = typeRelationship.GetGenericArguments()[0]; //Type attendu Type waitingType = relationship.PropertyType.GetGenericArguments()[0]; //Instanciation particulière lorsque le type attendu dans le BO est une List<Interface> if (waitingType.GetTypeInfo().IsInterface) { tempObj = Activator.CreateInstance(typeof(List <>).MakeGenericType(waitingType)); } //---------------------------// this.BindList(sendedType, tempObj, attr.First()); } else { this.BindModel(typeRelationship, tempObj, attr.First()); } relationship.SetValue(modelToBind, tempObj); } }
private IEnumerable <PropertyInfo> GetListProperties(Type type, string typeJson) { IEnumerable <PropertyInfo> properties = type.GetProperties() .Where(p => !AttributeHandling.GetIdsProperties(type).Contains(p)) .Where(p => !AttributeHandling.IsIgnoreJsonApi(p)) .Select(p => p); // Si des champs sont selectionnés, on récupere seulement les champs selectionés et les champs relations List <string> listSelected = this._fields.Where(m => m.Key == typeJson).Select(m => m.Value).FirstOrDefault(); if (listSelected != null) { properties = properties.Where(p => listSelected.Contains(AttributeHandling.GetLabelProperty(p)) || !Utils.IsTypeSystem(p.PropertyType) || !Utils.HasGenericTypeSystem(p.PropertyType)); } return(properties); }
/// <summary> /// Bind object property with simple type (string, bool, date, int) /// </summary> /// <param name="type">Type object</param> /// <param name="modelToBind">Instance object</param> /// <param name="attributes">List properties values</param> private void BindAttributes(Type type, object modelToBind, IEnumerable <JToken> attributes) { // Set known values foreach (JProperty attr in attributes) { PropertyInfo property = AttributeHandling.GetProperty(type, attr.Name); if (property == null) { this._error.Create(Constants.ERROR_STATUT_JSONAPI, $"Invalid Property {attr.Name}", $"{ AttributeHandling.GetLabelProperty(type)} has not property {attr.Name}", ""); } else if (property.CanWrite) { try { Type typeAttribute = AttributeHandling.GetTypeProperty(property); object valueFormat = this.ReadJsonValue(typeAttribute, attr); if (this.ValidateData(property, attr.Name, valueFormat)) { valueFormat = this.ResolveData(property, valueFormat); property.SetValue(modelToBind, valueFormat); } } catch (FormatException ex) { this._error.Create(Constants.ERROR_STATUT_JSONAPI, $"Error Format on attribute {attr.Name}", ex.Message, ""); } } } // Set empty properties with resolvers foreach (PropertyInfo property in type.GetProperties().Where(p => p.CanWrite && p.GetValue(modelToBind) == null)) { object valueResolved = this.ResolveData(property, null); if (valueResolved != null) { property.SetValue(modelToBind, valueResolved); } } }