Ejemplo n.º 1
0
 public async Task <ActionResult <object> > Add([FromBody] ManageEntityRequest request)
 {
     if (!_permissionService.IsAllowed(new ActionRequestInfo(HttpContext, _implementationsContainer, request.EntityType, ActionTypeEnum.Insert)))
     {
         return(Unauthorized());
     }
     return(await _entityHandler.Add(request));
 }
        private async Task <Result <object> > AddRecursive(ManageEntityRequest request, IDisposable repository, Dictionary <string, object> map
                                                           , string currentObjectPath, ActionContextInfo actionContext)
        {
            var    entityType = _implementations.Metadata[request.EntityTypeName];
            object entity;

            if (!entityType.NotMapped())
            {
                foreach (var prop in entityType.GetAllProperties().Where(x => x.DataType == DataTypes.NavigationEntity))
                {
                    if (prop.HideInInsert() || prop.ForeignKey == null)
                    {
                        continue;
                    }
                    if (actionContext.ExcludedProperties == null)
                    {
                        actionContext.ExcludedProperties = new List <string> {
                        };
                    }
                    (actionContext.ExcludedProperties as List <string>).Add(prop.ForeignKey.Name);
                }
                var result = await _entityHandler.Add(request, repository, actionContext);

                if (!result.Succeeded)
                {
                    // TODO: Here, the error messages should be prepended by the path to the current entity
                    return(result);
                }
                entity = result.Data;
            }
            else
            {
                entity = Activator.CreateInstance(_implementations.Reflector.GetType(request.EntityTypeName));
            }
            if (map.TryGetValue(currentObjectPath, out var existingValue))
            {
                existingValue.GetType().GetMethod("Add").Invoke(existingValue, new object[] { entity });
            }
            if (map.TryGetValue(currentObjectPath, out var list))
            {
                (list as IList).Add(entity);
            }
            else
            {
                map.Add(currentObjectPath, entity);
            }
            foreach (var pair in map)
            {
                if (!currentObjectPath.StartsWith(pair.Key))
                {
                    continue;
                }
                var itemType = pair.Value.GetType();
                if (itemType.IsGenericType)
                {
                    itemType = itemType.GetGenericArguments().Single();
                }
                var typeMetadata = _implementations.Metadata[itemType.Name];
                foreach (var property in typeMetadata.GetAllProperties())
                {
                    var path = JoinPath(pair.Key, property.Name);
                    if (path == currentObjectPath)
                    {
                        SetPropertyValue(pair.Value, property, entity);
                    }
                }
            }
            foreach (var propertyMetadata in entityType.GetAllProperties())
            {
                var propertyPath = JoinPath(currentObjectPath, propertyMetadata.Name);
                if (map.TryGetValue(propertyPath, out var val))
                {
                    SetPropertyValue(entity, propertyMetadata, val);
                }
                if (propertyMetadata.HideInInsert())
                {
                    continue;
                }
                var value = (request.Entity as JObject)[propertyMetadata.Name];
                //if (propertyMetadata.DataType == DataTypes.NavigationEntity)
                //{
                //	var relatedEntity = await AddRecursive(new ManageEntityRequest
                //	{
                //		EntityTypeName = propertyMetadata.EntityTypeName,
                //		Entity = value
                //	}, repository, map, propertyPath);
                //}
                if (propertyMetadata.DataType == DataTypes.NavigationList)
                {
                    map.Add(propertyPath, Activator.CreateInstance(typeof(List <>).MakeGenericType(_implementations.Reflector.GetType(propertyMetadata.EntityTypeName))));
                    if (!(value is IEnumerable collection))
                    {
                        continue;
                    }
                    foreach (var item in collection)
                    {
                        var childActionContext = new ActionContextInfo
                        {
                            CurrentEntity = item,
                            CurrentList   = collection,
                            EntityType    = _implementations.Metadata[propertyMetadata.EntityTypeName],
                            Masters       = actionContext.Masters.Concat(new MasterReference(entity, propertyMetadata)),
                            Parent        = actionContext,
                            Property      = propertyMetadata,
                            Type          = ActionContextType.Add
                        };
                        await AddRecursive(new ManageEntityRequest
                        {
                            EntityTypeName = propertyMetadata.EntityTypeName,
                            Entity         = item
                        }, repository, map, propertyPath, childActionContext);
                    }
                }
            }
            return(map[currentObjectPath]);
        }