public async Task <StoredFileDto> UploadAsync([FromForm] UploadFileInput input) { if (string.IsNullOrWhiteSpace(input.OwnerType)) { ModelState.AddModelError(nameof(input.OwnerType), $"{nameof(input.OwnerType)} must not be null"); } if (string.IsNullOrWhiteSpace(input.OwnerId)) { ModelState.AddModelError(nameof(input.OwnerId), $"{nameof(input.OwnerId)} must not be null"); } if (input.File == null) { ModelState.AddModelError(nameof(input.File), $"{nameof(input.File)} must not be null"); } if (!ModelState.IsValid) { throw new AbpValidationException("An error occured");//, ModelState.Keys.Select(k => new ValidationResult(ModelState.Values[k], new List<string>() { k }))); } var owner = await _dynamicRepository.GetAsync(input.OwnerType, input.OwnerId); if (owner == null) { throw new Exception($"Owner not found (type = '{input.OwnerType}', id = '{input.OwnerId}')"); } var uploadedFile = new StoredFileDto(); var fileName = input.File.FileName.CleanupFileName(); if (!string.IsNullOrWhiteSpace(input.PropertyName)) { // single file upload (stored as a property of an entity) var property = ReflectionHelper.GetProperty(owner, input.PropertyName); if (property == null || property.PropertyType != typeof(StoredFile)) { throw new Exception( $"Property '{input.PropertyName}' not found in class '{owner.GetType().FullName}'"); } if (property.GetValue(owner, null) is StoredFile storedFile) { storedFile.IsVersionControlled = true; var version = await _fileService.GetNewOrDefaultVersionAsync(storedFile); version.FileName = fileName; version.FileType = Path.GetExtension(fileName); await _fileVersionRepository.InsertOrUpdateAsync(version); await using (var fileStream = input.File.OpenReadStream()) { await _fileService.UpdateVersionContentAsync(version, fileStream); } // copy to the main todo: remove duplicated properties (filename, filetype), add a link to the last version and update it using triggers storedFile.FileName = version.FileName; storedFile.FileType = version.FileType; await _fileRepository.UpdateAsync(storedFile); } else { await using (var fileStream = input.File.OpenReadStream()) { storedFile = await _fileService.SaveFile(fileStream, fileName); property.SetValue(owner, storedFile, null); } } await _unitOfWorkManager.Current.SaveChangesAsync(); MapStoredFile(storedFile, uploadedFile); } else { // add file as an attachment (linked to an entity using OwnerType and OwnerId) await using (var fileStream = input.File.OpenReadStream()) { var storedFile = await _fileService.SaveFile(fileStream, fileName, file => { file.SetOwner(input.OwnerType, input.OwnerId); file.Category = input.FilesCategory; }); await _unitOfWorkManager.Current.SaveChangesAsync(); MapStoredFile(storedFile, uploadedFile); } } /* * 1. property of entity (ownerid+type+property) * 2. attachments list (ownerid+type+category) * 3. direct upload using id (id) */ return(uploadedFile); }
public async Task <object> GetEntityPropertyAsync <TEntity, TId>(TEntity entity, string propertyName) where TEntity : class, IEntity <TId> { var dynamicProperty = (await DtoTypeBuilder.GetEntityPropertiesAsync(entity.GetType())) .FirstOrDefault(p => p.Source == MetadataSourceType.UserDefined && p.Name == propertyName); if (dynamicProperty == null) { return(null); } var serializedValue = await GetValueAsync(entity, dynamicProperty); if (serializedValue == null) { return(null); } Type simpleType = null; switch (dynamicProperty.DataType) { case DataTypes.EntityReference: { var entityConfig = _entityConfigurationStore.Get(dynamicProperty.EntityType); var id = SerializationManager.DeserializeProperty(entityConfig.IdType, serializedValue); if (id == null) { return(null); } return(await _dynamicRepository.GetAsync(entityConfig.EntityType, id.ToString())); } case DataTypes.Boolean: simpleType = typeof(bool?); break; case DataTypes.Guid: simpleType = typeof(Guid?); break; case DataTypes.String: simpleType = typeof(string); break; case DataTypes.Date: case DataTypes.DateTime: simpleType = typeof(DateTime?); break; case DataTypes.Number: { switch (dynamicProperty.DataFormat) { case NumberFormats.Int32: simpleType = typeof(int?); break; case NumberFormats.Int64: simpleType = typeof(Int64?); break; case NumberFormats.Double: simpleType = typeof(double?); break; case NumberFormats.Float: simpleType = typeof(float?); break; } break; } case DataTypes.Time: simpleType = typeof(TimeSpan?); break; case DataTypes.Object: simpleType = typeof(string); break; } var rawValue = serializedValue != null && simpleType != null ? SerializationManager.DeserializeProperty(simpleType, serializedValue) : null; return(rawValue); }