public async Task <IActionResult> Update(int authorId, [ModelBinder(typeof(AuthorModelBinder))] AuthorUpsertDTO author) { try { _Logger.LogTrace($"Author {authorId} attempt"); if (author == null) { _Logger.LogTrace($"Author {authorId} attempt"); return(StatusCode(StatusCodes.Status400BadRequest, "Empty objecy is not allowed")); } if (!ModelState.IsValid) { return(StatusCode(StatusCodes.Status400BadRequest, ModelState)); } var authorToUpdate = await _BookStore.Authors.FindAsync( idPredicate : (x) => x.Id == authorId, includes : new Expression <Func <Author, object> >[] { x => x.Books }); if (authorToUpdate == null) { return(NotFound($"Unable to find author to update")); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var isUserAdmin = await _SignInManager.UserManager.IsInRoleAsync(user, AppDataSeeder.Administrator); if (!(authorToUpdate.OwnerId == user.Id || isUserAdmin)) { _Logger.LogWarning($"{user.Email} tried edit others author"); return(StatusCode(StatusCodes.Status403Forbidden, "Cant edit other's record")); } var differences = DataTools.FindDifferences <Book, BookUpsertDTO>( authorToUpdate.Books, author.Books, (o, n) => o.Id == n.Id); if (differences.InsertedItems?.Count > 0) { foreach (var newAuthorBook in differences.InsertedItems) { var authorBook = await _BookStore.Books.FindAsync(b => b.Id == newAuthorBook.Id); if (authorBook != null) { authorToUpdate.AuthorBooks.Add(new BookAuthor() { Author = authorToUpdate, AuthorId = authorToUpdate.Id, BookId = authorBook.Id, Book = authorBook }); } else { string message = $"Failed to find book with id {newAuthorBook.Id}"; _Logger.LogWarning(message); return(StatusCode(StatusCodes.Status422UnprocessableEntity, message)); } } foreach (var removedAuthorBook in differences.RemovedItems) { authorToUpdate.Books.Remove(removedAuthorBook); } } authorToUpdate = _Mapper.Map <AuthorUpsertDTO, Author>(author, authorToUpdate); bool succeed = await _BookStore.Authors.UpdateAsync(authorToUpdate); succeed &= await _BookStore.SaveData(); if (succeed) { return(StatusCode(StatusCodes.Status200OK, _Mapper.Map <AuthorUpsertDTO>(authorToUpdate))); } else { return(StatusCode(StatusCodes.Status500InternalServerError, "Unexpected error while updating the author")); } } catch (Exception e) { return(InternalError(e, "Unexpected error while updating the author")); } }
public async Task <IActionResult> Create([ModelBinder(typeof(AuthorModelBinder))] AuthorUpsertDTO author) { _Logger.LogInformation($"Author submition"); try { if (author == null) { _Logger.LogWarning($"Empty request was submited"); return(StatusCode(StatusCodes.Status400BadRequest)); } if (!ModelState.IsValid) { _Logger.LogWarning( $"Attempting to submit invalid data: {ModelState.Values.SelectMany(x => x.Errors).Select(e => e.ErrorMessage).Aggregate((fm, lm) => fm + '\n' + lm)}"); return(BadRequest(ModelState)); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var similarAuthors = await _BookStore.Authors.WhereAsync(filter : x => x.Firstname.ToLower().Equals(author.Firstname.ToLower()) && x.Lastname.ToLower().Equals(author.Firstname.ToLower()) && x.OwnerId == user.Id ); if (similarAuthors.Count > 0) { _Logger.LogWarning($"Possible duplicate for author {author.Firstname} {author.Lastname.ToUpper()}"); } Author writer = _Mapper.Map <Author>(author); writer.OwnerId = user.Id; var differences = DataTools.FindDifferences <Book, BookUpsertDTO>( writer.Books, author.Books, (o, n) => o.Id == n.Id); if (differences.InsertedItems?.Count > 0) { foreach (var newAuthorBook in differences.InsertedItems) { var authorBook = await _BookStore.Books.FindAsync(b => b.Id == newAuthorBook.Id); if (authorBook != null) { writer.AuthorBooks.Add(new BookAuthor() { Author = writer, BookId = authorBook.Id, Book = authorBook }); } else { string message = $"Failed to find book with id {newAuthorBook.Id}"; _Logger.LogWarning(message); return(StatusCode(StatusCodes.Status422UnprocessableEntity, message)); } } } var isSucceed = await _BookStore.Authors.CreateAsync(writer); isSucceed &= await _BookStore.SaveData(); if (!isSucceed) { _Logger.LogError("No records was inserted to database when creating the author"); return(StatusCode(StatusCodes.Status500InternalServerError, "Failed to save author")); } else { _Logger.LogInformation("Author creates successfully"); return(Created("Create", _Mapper.Map <AuthorUpsertDTO>(writer))); } } catch (Exception e) { return(InternalError(e, $"Unable to create author {author.Firstname} {author.Lastname}")); } }