public IActionResult UpdateBookForAuthor(Guid authorID, Guid bookID, [FromBody] BookUpdationDto book)
        {
            if (book == null)
            {
                return(BadRequest());
            }

            if (!libraryRepository.AuthorExists(authorID))
            {
                return(NotFound());
            }

            var bookforAuthor = libraryRepository.GetBookForAuthor(authorID, bookID);

            if (bookforAuthor == null)
            {
                // below piece of code defines UPSERTING in  put, for complete IF block
                var bookToAdd = Mapper.Map <BookUpdationDto, Book>(book);
                bookToAdd.Id = bookID;

                libraryRepository.AddBookForAuthor(authorID, bookToAdd);

                if (!libraryRepository.Save())
                {
                    throw new Exception($"updating book {bookID} for author{authorID} failed on save");
                }

                var bookToReturn = Mapper.Map <Book, BookDto>(bookToAdd);
                return(CreatedAtRoute("GetBookForAuthor", new { authorID = bookToReturn.AuthorId, bookID = bookToReturn.Id }, bookToReturn));
            }

            Mapper.Map <BookUpdationDto, Book>(book, bookforAuthor);

            libraryRepository.UpdateBookForAuthor(bookforAuthor);
            if (!libraryRepository.Save())
            {
                throw new Exception($"updating book {bookID} for author{authorID} failed on save");
            }

            return(NoContent());
        }
        public IActionResult PartiallyUpdateBookForAuthor(Guid authorID, Guid bookID, [FromBody] JsonPatchDocument <BookUpdationDto> patchDoc)
        {
            //always use content type (media type) as application/json-patch+json
            if (patchDoc == null)
            {
                return(BadRequest());
            }

            if (!libraryRepository.AuthorExists(authorID))
            {
                return(NotFound());
            }

            var bookforAuthor = libraryRepository.GetBookForAuthor(authorID, bookID);

            if (bookforAuthor == null)
            {
                //return NotFound();
                // UPSERTING with PATCH in this if block
                var bookDto = new BookUpdationDto();
                patchDoc.ApplyTo(bookDto);

                var bookToAdd = Mapper.Map <Book>(bookDto);
                bookToAdd.Id = bookID;

                libraryRepository.AddBookForAuthor(authorID, bookforAuthor);
                if (!libraryRepository.Save())
                {
                    throw new Exception($"patching book {bookID} for author{authorID} failed on save");
                }

                var bookToReturn = Mapper.Map <BookDto>(bookToAdd);

                return(CreatedAtRoute("GetBookForAuthor", new { authorID = authorID, bookID = bookToReturn.Id }, bookToReturn));
            }

            var bookToPatch = Mapper.Map <BookUpdationDto>(bookforAuthor);

            ////patchDoc.ApplyTo(bookToPatch, ModelState);

            patchDoc.ApplyTo(bookToPatch);

            if (bookToPatch.Title == bookToPatch.Description)
            {
                ModelState.AddModelError(nameof(BookUpdationDto), "title and description cant be same");
            }

            TryValidateModel(bookToPatch);


            //add validation
            if (!ModelState.IsValid)
            {
                return(new UnprocessableEntityObjectResult(ModelState));
            }


            Mapper.Map <BookUpdationDto, Book>(bookToPatch, bookforAuthor);

            libraryRepository.UpdateBookForAuthor(bookforAuthor);
            if (!libraryRepository.Save())
            {
                throw new Exception($"patching book {bookID} for author{authorID} failed on save");
            }

            return(NoContent());
        }