private BookReview CreateUpdateReview(BookReview review, bool create) { OpContext.ThrowIfNull(review, ClientFaultCodes.ContentMissing, "Review", "Review object in message body is missing."); //find book var session = OpenSession(); var bk = session.GetEntity <IBook>(review.BookId); //Validate using ValidationExtensions methods //will throw and return BadRequest if book Id is invalid OpContext.ThrowIfNull(bk, ClientFaultCodes.ObjectNotFound, "BookId", "Book not found. ID={0}", review.BookId); //Validate input fields OpContext.ValidateNotEmpty(review.Caption, "Caption", "Caption may not be empty."); OpContext.ValidateNotEmpty(review.Review, "Review", "Review text may not be empty."); OpContext.ValidateMaxLength(review.Caption, 100, "Caption", "Caption text is too long."); // Review text is unlimited in database, but let's still limit it to 1000 chars OpContext.ValidateMaxLength(review.Review, 1000, "Review", "Review text is too long, must be under 1000 chars"); OpContext.ValidateRange(review.Rating, 1, 5, "Rating", "Rating must be between 1 and 5"); OpContext.ThrowValidation(); //will throw if any faults had been detected; will return BadRequest with list of faults in the body // get user; var user = session.GetEntity <IUser>(OpContext.User.UserId); // with AuthenticatedOnly attribute, we should always have user; still check just in case OpContext.ThrowIfNull(user, ClientFaultCodes.ObjectNotFound, "User", "Current user not identified."); //Create/update review entity IBookReview entReview; if (create) { entReview = session.NewReview(user, bk, review.Rating, review.Caption, review.Review); } else { entReview = session.GetEntity <IBookReview>(review.Id); OpContext.ThrowIfNull(entReview, ClientFaultCodes.ObjectNotFound, "Review", "Review object not found, ID={0}.", review.Id); entReview.Caption = review.Caption; entReview.Rating = review.Rating; entReview.Review = review.Review; } session.SaveChanges(); return(entReview.ToModel(details: true)); }