/// <summary>
        /// Creates a generic upload.
        /// </summary>
        /// <param name="model">The upload to create.</param>
        /// <param name="unitOfWork">Unit of work.</param>
        /// <returns>Upload populated with newly allocated upload identifier.</returns>
        private Upload CreateUpload(CreateUploadModel model, IUnitOfWork unitOfWork)
        {
            // Validate create upload model
            _uploadValidator.ValidateCreateUpload(model);

            // Construct upload object
            DateTime now    = DateTime.UtcNow;
            Upload   upload = new Upload
            {
                TenantId    = model.TenantId,
                Created     = now,
                Updated     = now,
                Name        = model.Name.Trim(),
                Content     = model.Content,
                ContentType = model.ContentType.Trim().ToLower(),
                Size        = model.Content.Length,
                UploadType  = UploadType.Upload,
                Committed   = false
            };

            // Create upload and record newly allocated upload identifier
            upload.UploadId = _uploadRepository.CreateUpload(upload, unitOfWork);

            // Return upload object
            return(upload);
        }
        /// <summary>
        /// Creates an image.
        /// </summary>
        /// <param name="model">The upload to create.</param>
        /// <param name="unitOfWork">Unit of work.</param>
        /// <returns>Image populated with newly allocated upload identifier.</returns>
        private Image CreateImage(CreateUploadModel model, IUnitOfWork unitOfWork)
        {
            // Validate create upload model
            Drawing.Size?size = _uploadValidator.ValidateCreateImage(model);

            // Construct image object
            DateTime now   = DateTime.UtcNow;
            Image    image = new Image
            {
                TenantId    = model.TenantId,
                Created     = now,
                Updated     = now,
                Name        = model.Name.Trim(),
                Content     = model.Content,
                ContentType = model.ContentType.Trim().ToLower(),
                Size        = model.Content.Length,
                UploadType  = UploadType.Image,
                Committed   = false,
                Width       = size.Value.Width,
                Height      = size.Value.Height
            };

            // Create image and record newly allocated upload identifier
            image.UploadId = _uploadRepository.CreateImage(image, unitOfWork);

            // Return image object
            return(image);
        }
 /// <summary>
 /// Checks that content type is specified and valid.
 /// </summary>
 /// <param name="model">Create upload details.</param>
 /// <param name="keyPrefix">Validation key prefix.</param>
 public void ValidateCreateContentType(CreateUploadModel model, string keyPrefix = null)
 {
     if (string.IsNullOrWhiteSpace(model.ContentType))
     {
         throw new ValidationErrorException(new ValidationError(UploadPropertyNames.ContentType, UploadResource.ContentTypeRequiredMessage, keyPrefix));
     }
 }
        /// <summary>
        /// Creates a new upload with uncommitted state.
        /// </summary>
        /// <param name="model">The upload to create.</param>
        /// <param name="unitOfWork">Unit of work.</param>
        /// <returns>Newly allocated upload identfier.</returns>
        public long Create(CreateUploadModel model, IUnitOfWork unitOfWork = null)
        {
            // If we don't have a unit of work in place, create one now so that we can rollback all changes in case of failure
            IUnitOfWork localUnitOfWork = unitOfWork == null?_unitOfWorkFactory.CreateUnitOfWork() : null;

            // Try to create upload
            try
            {
                // The first thing we need to check is that content type is specified
                _uploadValidator.ValidateCreateContentType(model);

                // Get upload type, which will determine how upload is stored
                UploadType uploadType = GetUploadType(model.ContentType);

                // Construct upload given upload type and content
                Upload upload = null;
                switch (uploadType)
                {
                case UploadType.Image:
                    upload = CreateImage(model, unitOfWork ?? localUnitOfWork);
                    break;

                case UploadType.Upload:
                    upload = CreateUpload(model, unitOfWork ?? localUnitOfWork);
                    break;
                }

                // Create upload in storage
                _storageService.Create(upload, GetUncommittedStorageHierarchy(), unitOfWork ?? localUnitOfWork);

                // Commit work if local unit of work in place, then return newly allocated upload identifier
                if (localUnitOfWork != null)
                {
                    localUnitOfWork.Commit();
                }
                return(upload.UploadId);
            }
            catch
            {
                if (localUnitOfWork != null)
                {
                    localUnitOfWork.Rollback();
                }
                throw;
            }
            finally
            {
                if (localUnitOfWork != null)
                {
                    localUnitOfWork.Dispose();
                }
            }
        }
        /// <summary>
        /// Validates information supplied to create a new image.
        /// </summary>
        /// <param name="model">Create image details.</param>
        /// <param name="keyPrefix">Validation key prefix.</param>
        /// <returns>Width and height of image.</returns>
        public Size?ValidateCreateImage(CreateUploadModel model, string keyPrefix)
        {
            // Perform generic upload checks
            ValidateCreateUpload(model, keyPrefix);

            // Check that upload is image
            Size?size = _imageAnalysisService.GetImageDimensions(model.Content);

            if (size == null)
            {
                throw new ValidationErrorException(new ValidationError(UploadPropertyNames.Content, UploadResource.ImageInvalidMessage, keyPrefix));
            }

            // Return dimensions of image
            return(size);
        }