skylake skylake - 2 months ago 9
C# Question

Validation failed for one or more entities. MVC

I'm getting following error when I try to create a row for

CommentToReview
model via action
CreateComment
.


Validation failed for one or more entities. See
'EntityValidationErrors' property for more details.


I'm doing something wrong with data I'm sending to my model, but I don't know what. I also tried with
(DbEntityValidationException e)
method without success since I couldn't make it work with my code as I'm not an experienced coder and new to MVC.

Code below is from my controller:

// GET: Review/Create
[HttpGet]
public ActionResult CreateComment() {
return View();
}

// POST: Review/Create
[HttpPost]
public ActionResult CreateComment(Guid? id) {
if (ModelState.IsValid)
{

Guid userID = new Guid(Session["LoggedUserID"].ToString());
Guid reviewID = new Guid(id.ToString());


CommentToReview rComment = new CommentToReview();

rComment.UserId = userID;
rComment.ReviewId = reviewID;
rComment.CreatedDate = DateTime.Now;


db.CommentToReviews.Add(rComment);
db.SaveChanges();

return RedirectToAction("Index");
}
return View();
}


Model for CommentToReview:

public System.Guid Id { get; set; }
public System.Guid UserId { get; set; }
public System.Guid ReviewId { get; set; }
public string Comment { get; set; }
public System.DateTime CreatedDate { get; set; }


How I send data to model:


  • Id
    is generating its own Guid key

  • UserID
    gets its Id from
    Session["LoggedUserID"]

  • Comment
    is created trough View

  • The rest gets it data trough the code in controller.



View code for CreateComment:

@model xxxx.CommentToReview

@{
ViewBag.Title = "CreateComment";
}

<h2>CreateComment</h2>

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>CommentToReview</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<div class="form-group">
@Html.LabelFor(model => model.Comment, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Comment, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Comment, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

Answer

Since you are writing the comment for a review, you should accept the review id in your GET action method as a param, create an object of CommentReviewVm class and set the ReviewId property and send to the view.

So your view model will be

public class CommentReviewVm
{
  public Guid ReviewId { set;get;}
  [Required]
  public string Comment { set;get;}
}

in your Action method,

public ActionResult CreateComment(Guid id)
{
  return View(new CommentReviewVm { ReviewId=id});
}

So when someone comes to this GET action, they need to pass the Id(which is the review id). Ex : yourSiteName\Review\CreateComment\6ae6469d-8531-4bb6-8214-dbc65016288f

Now in your view, you need to keep this ReviewId in a hidden field so that when you submit the form it will be available in the HttpPost action method.

@model CommentReviewVm
@using(Html.BeginForm())
{
  @Html.HiddenFor(s=>s.ReviewId) 
  @Html.LabelFor(f=>f.Comment)
  @Html.TextBoxFor(g=>g.Comment)
  <input type="submit" />
}

Now in your HttpPost action method, use this view model as your parameter and read the values and use it for saving

[HttpPost]
public ActionResult CreateComment(CommentReviewVm model)
{
  if(ModelState.IsValid)
  {
     var m = new CommentReview { Comment = model.Comment, ReviewId=model.ReviewId };
     m.userID = new Guid(Session["LoggedUserID"].ToString());       
     m.CreatedDate = DateTime.Now;
     db.CommentToReviews.Add(m);
     db.SaveChanges();
     return RedirectToAction("Index");
  }
  return View(model);
} 

I see you are manually setting the ReviewId(Guid) in the code. I am not sure what value you want there. If you are adding the comment againist a review, You should be getting the review id when you call the CreateComment action method (should be part of the url as i explained in the first paragraph). If that is not the case, make adjustments to the HttpPost action method to fill that value in,

Comments