예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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));
                    }
                }
            }
        }
예제 #3
0
        /// <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)]);
                }
            }
        }
예제 #4
0
        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));
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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);
                }
            }
        }