Entity collection converter.
Inheritance: System.ComponentModel.TypeConverter
Esempio n. 1
0
        /// <summary>
        /// Update property for entity.
        /// </summary>
        /// <param name="entity">Entity to update.</param>
        /// <param name="propertyMetadata">Property metadata.</param>
        /// <returns></returns>
        public async Task UpdateProperty(TEntity entity, IPropertyMetadata propertyMetadata)
        {
            if (propertyMetadata.EditRoles.Count() > 0 &&
                !(propertyMetadata.AuthenticationRequiredMode == AuthenticationRequiredMode.All ?
                  propertyMetadata.EditRoles.All(r => Controller.User.IsInRole(r)) :
                  propertyMetadata.EditRoles.Any(r => Controller.User.IsInRole(r))))
            {
                return;
            }
            if (propertyMetadata.IsFileUpload)
            {
                #region File Path Value
                if (!Controller.Request.Files.AllKeys.Contains(propertyMetadata.ClrName))
                {
                    return;
                }
                if (!(Controller is IFileController <TEntity>))
                {
                    if (propertyMetadata.ClrType != typeof(byte[]))
                    {
                        throw new NotSupportedException("Controller doesn't support upload file.");
                    }
                    if (Controller.Request.Files.AllKeys.Contains(propertyMetadata.ClrName))
                    {
                        var          file   = Controller.Request.Files[propertyMetadata.ClrName];
                        MemoryStream stream = new MemoryStream();
                        await file.InputStream.CopyToAsync(stream);

                        propertyMetadata.SetValue(entity, stream.ToArray());
                        stream.Close();
                        stream.Dispose();
                    }
                }
                else
                {
                    await((IFileController <TEntity>)Controller).SaveFileToProperty(entity, propertyMetadata, Controller.Request.Files[propertyMetadata.ClrName]);
                }
                #endregion
            }
            else
            {
                if (!Controller.Request.Form.AllKeys.Contains(propertyMetadata.ClrName))
                {
                    return;
                }
                string        value     = Controller.Request.Form[propertyMetadata.ClrName];
                TypeConverter converter = EntityValueConverter.GetConverter(propertyMetadata);
                if (converter == null)
                {
                    if (propertyMetadata.ClrType.IsGenericType && propertyMetadata.ClrType.GetGenericTypeDefinition() == typeof(ICollection <>))
                    {
                        converter = new Converter.CollectionConverter();
                    }
                    else if (propertyMetadata.ClrType.IsEnum)
                    {
                        converter = new EnumConverter(propertyMetadata.ClrType);
                    }
                    else
                    {
                        converter = TypeDescriptor.GetConverter(propertyMetadata.ClrType);
                        if (converter == null && propertyMetadata.Type != ComponentModel.DataAnnotations.CustomDataType.Password)
                        {
                            throw new NotSupportedException("Type of \"" + propertyMetadata.ClrName + "\" converter not found.");
                        }
                    }
                }
                if (propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.Password && entity is IPassword)
                {
                    object v = propertyMetadata.GetValue(entity);
                    if (v == null || value != v.ToString())
                    {
                        ((IPassword)entity).SetPassword(value);
                    }
                }
                else
                {
                    EntityValueConverterContext context = new EntityValueConverterContext(EntityBuilder.DescriptorContext, propertyMetadata);
                    object cvalue;
                    try
                    {
                        cvalue = converter.ConvertFrom(context, null, value);
                    }
                    catch (Exception ex)
                    {
                        Controller.ViewBag.ErrorMessage = ex.Message;
                        return;
                    }
                    if (converter.GetType() == typeof(Converter.CollectionConverter))
                    {
                        object collection = propertyMetadata.GetValue(entity);
                        ((dynamic)collection).Clear();
                        var      addMethod = collection.GetType().GetMethod("Add");
                        object[] array     = (object[])cvalue;
                        for (int a = 0; a < array.Length; a++)
                        {
                            addMethod.Invoke(collection, new object[] { array[a] });
                        }
                    }
                    else
                    {
                        propertyMetadata.SetValue(entity, cvalue);
                    }
                }
            }
        }
        public virtual ActionResult Update(Guid id)
        {
            TEntity entity;

            if (id == Guid.Empty)
            {
                if (!EntityQueryable.Addable())
                {
                    return(new HttpStatusCodeResult(403));
                }
                if (!Metadata.AddRoles.All(t => User.IsInRole(t)))
                {
                    return(new HttpStatusCodeResult(403));
                }
                entity = EntityQueryable.Create();
            }
            else
            {
                if (!EntityQueryable.Editable())
                {
                    return(new HttpStatusCodeResult(403));
                }
                if (!Metadata.EditRoles.All(t => User.IsInRole(t)))
                {
                    return(new HttpStatusCodeResult(403));
                }
                entity = EntityQueryable.GetEntity(id);
                if (entity == null)
                {
                    return(new HttpStatusCodeResult(404));
                }
            }
            var properties = Metadata.Properties.Where(t => !t.IsHiddenOnEdit).ToArray();

            for (int i = 0; i < properties.Length; i++)
            {
                PropertyMetadata propertyMetadata = properties[i];
                if (propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.File || propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.Image)
                {
                    #region File Path Value
                    if (!Request.Files.AllKeys.Contains(propertyMetadata.Property.Name))
                    {
                        continue;
                    }
                    if (!(this is IFileController <TEntity>))
                    {
                        throw new NotSupportedException("Controller doesn't support upload file.");
                    }
                    ((IFileController <TEntity>) this).SaveFileToProperty(entity, propertyMetadata, Request.Files[propertyMetadata.Property.Name]);
                    #endregion
                }
                else
                {
                    #region Property Value
                    if (!Request.Form.AllKeys.Contains(propertyMetadata.Property.Name))
                    {
                        if (id == Guid.Empty && propertyMetadata.IsRequired)
                        {
                            Response.StatusCode = 400;
                            return(Content(propertyMetadata.Name + "为必填项"));
                        }
                        continue;
                    }
                    string originValue = Request.Form[propertyMetadata.Property.Name];
                    if (string.IsNullOrEmpty(originValue) && propertyMetadata.Property.PropertyType != typeof(string) && propertyMetadata.IsRequired)
                    {
                        Response.StatusCode = 400;
                        return(Content(propertyMetadata.Name + "为必填项"));
                    }
                    //Type type = propertyMetadata.Property.PropertyType;
                    //if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    //    type = type.GetGenericArguments()[0];
                    TypeConverter converter = EntityValueConverter.GetConverter(propertyMetadata);
                    if (converter == null)
                    {
                        if (propertyMetadata.Property.PropertyType.IsGenericType && propertyMetadata.Property.PropertyType.GetGenericTypeDefinition() == typeof(ICollection <>))
                        {
                            converter = new Converter.CollectionConverter();
                        }
                        else if (propertyMetadata.Property.PropertyType.IsEnum)
                        {
                            converter = new EnumConverter(propertyMetadata.Property.PropertyType);
                        }
                        else
                        if (propertyMetadata.Type != ComponentModel.DataAnnotations.CustomDataType.Password)
                        {
                            throw new NotSupportedException("Type of \"" + propertyMetadata.Property.PropertyType.Name + "\" converter not found.");
                        }
                    }
                    if (propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.Password && entity is IPassword)
                    {
                        object v = propertyMetadata.Property.GetValue(entity);
                        if (v == null || originValue != v.ToString())
                        {
                            ((IPassword)entity).SetPassword(originValue);
                        }
                    }
                    else
                    {
                        EntityValueConverterContext context = new EntityValueConverterContext(EntityBuilder.DescriptorContext, propertyMetadata);
                        object value = converter.ConvertFrom(context, null, originValue);
                        if (converter.GetType() == typeof(Converter.CollectionConverter))
                        {
                            object collection = propertyMetadata.Property.GetValue(entity);
                            ((dynamic)collection).Clear();
                            var      addMethod = collection.GetType().GetMethod("Add");
                            object[] array     = (object[])value;
                            for (int a = 0; a < array.Length; a++)
                            {
                                addMethod.Invoke(collection, new object[] { array[a] });
                            }
                        }
                        else
                        {
                            propertyMetadata.Property.SetValue(entity, value);
                        }
                    }
                    #endregion
                }
            }
            var validateResult = entity.Validate(null);
            if (validateResult.Count() != 0)
            {
                Response.StatusCode = 400;
                return(Content(new string(validateResult.SelectMany(t => t.ErrorMessage += "/r/n").ToArray())));
            }
            bool result;
            if (id == Guid.Empty)
            {
                result = EntityQueryable.Add(entity);
            }
            else
            {
                result = EntityQueryable.Edit(entity);
            }
            if (result)
            {
                return(Content(entity.Index.ToString()));
            }
            else
            {
                Response.StatusCode = 400;
                return(Content("未知"));
            }
        }