Beispiel #1
0
        public async Task <StoredFileDto> GetEntityPropertyAsync([FromQuery] StoredFileAsPropertyDto input)
        {
            if (string.IsNullOrWhiteSpace(input.OwnerType) ||
                string.IsNullOrWhiteSpace(input.OwnerId) ||
                string.IsNullOrWhiteSpace(input.PropertyName))
            {
                return(null);
            }

            var owner = await _dynamicRepository.GetAsync(input.OwnerType, input.OwnerId);

            if (owner == null)
            {
                return(null);
            }

            var property = ReflectionHelper.GetProperty(owner, input.PropertyName);

            if (property == null)
            {
                throw new Exception($"Property '{input.PropertyName}' not found in the class {owner.GetType().Name}");
            }

            if (!(property.GetValue(owner) is StoredFile storedFile && !storedFile.IsDeleted))
            {
                return(null);
            }

            return(GetFileDto(storedFile));
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        public async Task <StoredFileDto> CreateOrUpdateAsync([FromForm] CreateStoredFileInput input)
        {
            if (input.File == null)
            {
                ModelState.AddModelError(nameof(input.File), $"{nameof(input.File)} must not be null");
            }

            var ownerSpecified =
                !string.IsNullOrWhiteSpace(input.OwnerType) && !string.IsNullOrWhiteSpace(input.OwnerId);

            if (string.IsNullOrWhiteSpace(input.OwnerId) && !string.IsNullOrWhiteSpace(input.OwnerType))
            {
                ModelState.AddModelError(nameof(input.OwnerId), $"{nameof(input.OwnerId)} must not be null when {nameof(input.OwnerType)} is specified");
            }

            if (string.IsNullOrWhiteSpace(input.OwnerType) && !string.IsNullOrWhiteSpace(input.OwnerId))
            {
                ModelState.AddModelError(nameof(input.OwnerType), $"{nameof(input.OwnerType)} must not be null when {nameof(input.OwnerId)} is specified");
            }

            if (input.Id == null && string.IsNullOrWhiteSpace(input.PropertyName))
            {
                ModelState.AddModelError(nameof(input.Id), $"Id must not be null");
            }

            var owner = ownerSpecified
                ? await _dynamicRepository.GetAsync(input.OwnerType, input.OwnerId)
                : null;

            if (ownerSpecified && owner == null)
            {
                ModelState.AddModelError(input.OwnerId, $"Owner not found (type = '{input.OwnerType}', id = '{input.OwnerId}')");
            }

            var uploadAsProperty = owner != null && !string.IsNullOrWhiteSpace(input.PropertyName);
            var property         = uploadAsProperty
                ? ReflectionHelper.GetProperty(owner, input.PropertyName)
                : null;

            if (uploadAsProperty)
            {
                if (property == null)
                {
                    ModelState.AddModelError(nameof(input.PropertyName), $"Property '{owner.GetType().Name}.{input.PropertyName}' not found");
                }

                if (property != null && !typeof(StoredFile).IsAssignableFrom(property.PropertyType))
                {
                    ModelState.AddModelError(nameof(input.PropertyName), $"Wrong type of '{owner.GetType().Name}.{input.PropertyName}' property (actual: '{property.PropertyType.FullName}', expected: '{nameof(StoredFile)}')");
                }
            }

            if (!ModelState.IsValid)
            {
                throw new AbpValidationException("Failed to upload file", GetValidationResults(ModelState));
            }

            StoredFile storedFile;

            // allow to use predefined Id and re-activate existing storedfile
            using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
            {
                storedFile = input.Id != null
                    ? await _fileRepository.GetAll().FirstOrDefaultAsync(f => f.Id == input.Id.Value)
                    : property != null
                        ? property.GetValue(owner) as StoredFile
                        : null;
            }

            var fileName = input.File.FileName.CleanupFileName();

            if (storedFile == null)
            {
                await using (var fileStream = input.File.OpenReadStream())
                {
                    storedFile = await _fileService.SaveFile(fileStream, fileName, file =>
                    {
                        // set predefined Id
                        if (input.Id.HasValue && input.Id.Value != Guid.Empty)
                        {
                            file.Id = input.Id.Value;
                        }
                    });

                    // set property if needed
                    if (property != null)
                    {
                        property.SetValue(owner, storedFile, null);
                        await _dynamicRepository.SaveOrUpdateAsync(owner);
                    }
                }
            }
            else
            {
                storedFile.IsDeleted           = false;
                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);
            }

            var uploadedFile = new StoredFileDto();
            await _unitOfWorkManager.Current.SaveChangesAsync();

            MapStoredFile(storedFile, uploadedFile);

            return(uploadedFile);
        }
Beispiel #4
0
        public async Task <bool> Delete([FromQuery] DeleteStoredFileInput input)
        {
            var ownerSpecified =
                !string.IsNullOrWhiteSpace(input.OwnerType) && !string.IsNullOrWhiteSpace(input.OwnerId);

            if (string.IsNullOrWhiteSpace(input.OwnerId) && !string.IsNullOrWhiteSpace(input.OwnerType))
            {
                ModelState.AddModelError(nameof(input.OwnerId), $"{nameof(input.OwnerId)} must not be null when {nameof(input.OwnerType)} is specified");
            }

            if (string.IsNullOrWhiteSpace(input.OwnerType) && !string.IsNullOrWhiteSpace(input.OwnerId))
            {
                ModelState.AddModelError(nameof(input.OwnerType), $"{nameof(input.OwnerType)} must not be null when {nameof(input.OwnerId)} is specified");
            }

            if (input.FileId == null && string.IsNullOrWhiteSpace(input.PropertyName))
            {
                ModelState.AddModelError(nameof(input.FileId), $"Id must not be null");
            }

            var owner = ownerSpecified
                ? await _dynamicRepository.GetAsync(input.OwnerType, input.OwnerId)
                : null;

            if (ownerSpecified && owner == null)
            {
                ModelState.AddModelError(input.OwnerId, $"Owner not found (type = '{input.OwnerType}', id = '{input.OwnerId}')");
            }

            var processAsProperty = owner != null && !string.IsNullOrWhiteSpace(input.PropertyName);
            var property          = processAsProperty
                ? ReflectionHelper.GetProperty(owner, input.PropertyName)
                : null;

            if (processAsProperty)
            {
                if (property == null)
                {
                    ModelState.AddModelError(nameof(input.PropertyName), $"Property '{owner.GetType().Name}.{input.PropertyName}' not found");
                }

                if (property != null && !typeof(StoredFile).IsAssignableFrom(property.PropertyType))
                {
                    ModelState.AddModelError(nameof(input.PropertyName), $"Wrong type of '{owner.GetType().Name}.{input.PropertyName}' property (actual: '{property.PropertyType.FullName}', expected: '{nameof(StoredFile)}')");
                }
            }

            if (!ModelState.IsValid)
            {
                throw new AbpValidationException("Failed to delete file", GetValidationResults(ModelState));
            }

            var storedFile = input.FileId != null
                ? await _fileRepository.GetAll().FirstOrDefaultAsync(f => f.Id == input.FileId.Value)
                : property != null
                    ? property.GetValue(owner) as StoredFile
                    : null;

            if (storedFile != null)
            {
                // if the `property` is specified - then it's direct link and we should set it to null
                if (property != null)
                {
                    property.SetValue(owner, null, null);
                    await _dynamicRepository.SaveOrUpdateAsync(owner);
                }

                await _fileService.DeleteAsync(storedFile);
            }

            return(true);
        }