public async Task <IActionResult> Create([ModelBinder(typeof(BookModelBinder))] BookUpsertDTO book) { _Logger.LogTrace("Attempt to create the book"); try { if (book == null) { return(BookBadRequest("Attempt to insert empty book")); } if (!ModelState.IsValid) { return(BookBadRequest("Attempt to insert the invalid book", ModelState)); } Task <ImageData> imageUpload = null; CancellationTokenSource cts = null; if (book.ImageWasChanged) { cts = new CancellationTokenSource(); imageUpload = _ImageService.SetImage(book.Image, cts.Token, String.Empty); book.Image = String.Empty; } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); Book bookRecord = _Mapper.Map <Book>(book); bookRecord.OwnerId = user.Id; var differences = DataTools.FindDifferences <BookAuthor, AuthorUpsertDTO>( bookRecord.BookAuthors, book.Authors, (old, nw) => old.AuthorId == nw.Id); foreach (var inserted in differences.InsertedItems) { Author author = await _BookStore.Authors.FindAsync(x => x.Id == inserted.Id); if (author != null) { bookRecord.BookAuthors.Add(new BookAuthor() { AuthorId = inserted.Id, Author = author, Book = bookRecord }); } else { cts?.Cancel(); return(StatusCode(StatusCodes.Status422UnprocessableEntity, "One of the book authors not exists in database, operation cancelled")); } } foreach (var removed in differences.RemovedItems) { bookRecord.BookAuthors.Remove(removed); } if (imageUpload != null) { ImageData imageData = await imageUpload; bookRecord.Image = imageData.Name; bookRecord.Thumbnail = imageData.Base64ThumbNail; } bool result = await _BookStore.Books.CreateAsync(bookRecord); result &= await _BookStore.SaveData(); if (result) { _Logger.LogInformation($"Book succesfully created, assigned id {bookRecord.Id}"); return(StatusCode(StatusCodes.Status201Created, bookRecord)); } else { return(InternalError("Failed to create book")); } } catch (AggregateException e) { _Logger.LogError(e.Flatten(), e.Flatten().Message, e.Flatten().InnerExceptions?.Select(ie => $"{ie.Message}/n{new string('-', 20)}/n{ie.StackTrace}")); return(InternalError("Failed to create the book", e)); } catch (Exception e) { _Logger.LogError(e, e.Message); return(InternalError("Failed to create bool", e)); } }
public async Task <IActionResult> Update(int bookId, [ModelBinder(typeof(BookModelBinder))] BookUpsertDTO book) { _Logger.LogInformation("Attempting to update book"); try { if (book == null) { return(BookBadRequest("Book object must be not empty")); } if (bookId <= 0) { return(BookBadRequest($"Book id you provided ({bookId}) is inferior of 0 and not exists in database")); } if (!ModelState.IsValid) { return(BookBadRequest("Book data not passed the validation", ModelState)); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var isUserAdministrator = await _SignInManager.UserManager.IsInRoleAsync(user, AppDataSeeder.Administrator); var srcBook = await _BookStore.Books.FindAsync(idPredicate : (x) => x.Id == bookId, includes : new Expression <Func <Book, object> >[] { x => x.BookAuthors }); if (srcBook == null) { return(BookNotFound($"Book id you provided ({bookId}) not found and can not be updated")); } if (!(srcBook.OwnerId == user.Id || isUserAdministrator)) { _Logger.LogWarning($"{user.Email} tried edit others book"); return(StatusCode(StatusCodes.Status403Forbidden, "Cant edit other's record")); } Task <ImageData> imageTask = null; CancellationTokenSource cancellationTokenSource = null; string originalImageName = srcBook.Image; if (book.ImageWasChanged) { cancellationTokenSource = new CancellationTokenSource(); imageTask = _ImageService.SetImage(book.Image, cancellationTokenSource.Token, srcBook.Image); book.Image = srcBook.Image; } else { book.Image = srcBook.Image; } #region Updating authors list var differences = DataTools.FindDifferences <BookAuthor, AuthorUpsertDTO>( srcBook.BookAuthors, book.Authors, (old, nw) => old.AuthorId == nw.Id); foreach (var inserted in differences.InsertedItems) { Author author = await _BookStore.Authors.FindAsync(x => x.Id == inserted.Id); if (author != null) { srcBook.BookAuthors.Add(new BookAuthor() { AuthorId = inserted.Id, Author = author, Book = srcBook, BookId = srcBook.Id }); } else { cancellationTokenSource?.Cancel(); return(StatusCode(StatusCodes.Status422UnprocessableEntity, "One of the book authors not exists in database, operation cancelled")); } } foreach (var removed in differences.RemovedItems) { srcBook.BookAuthors.Remove(removed); } srcBook = _Mapper.Map <BookUpsertDTO, Book>(book, srcBook); #endregion if (imageTask != null) { var imageData = await imageTask; srcBook.Image = imageData.Name; srcBook.Thumbnail = imageData.Base64ThumbNail; } bool result = await _BookStore.Books.UpdateAsync(srcBook); result &= await _BookStore.SaveData(); if (result) { _Logger.LogTrace("Book id {bookId} was updated in the database"); return(StatusCode(StatusCodes.Status200OK, srcBook)); } else { return(InternalError($"Failed to update book {bookId}")); } } catch (Exception e) { return(InternalError("Failed to update the book", e)); } }