Why is POST action losing model values?
asp.net-mvc, c#
Solution
You will need to store the values for ProjectId and ActorId as Hidden Inputs on your form so that they can be included in the posted values sent back to your controller action.
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(x => x.ProjectId)
@Html.HiddenFor(x => x.ActorId)
...
}
Problem
I have a ViewModel which I'm trying to post back to save in the DB. While the ViewModel is getting the values set in the `//GET Create(int id)` it is losing some of them by the time it gets to the `//POST Create ()`. The `GoalLevel` and `GoalTitle` are being passed through OK, but the `ActorId` and `ProjectId` are being lost and even though the debugger is going through the `if (Model.State.IsValid)` block, the values that are going through aren't being saved to the DB. The redirect then falls over, because I've no longer got a valid `ProjectId` to pass to the URL. I'm sure it's something obvious if you know what you're doing! CONTROLLER ``` // GET: UseCases/Create public ActionResult Create(int id) { ViewBag.projectId = id; //Populate the ViewModel UserGoalsStepViewModel model = new UserGoalsStepViewModel() { ProjectId = id, ActorList = new SelectList(db.Actors.Where(a => a.projectID == id), "id", "Title"), }; return View(model); } // POST: UseCases/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "ProjectId,ActorId,GoalTitle,Level")] UserGoalsStepViewModel model) { if (ModelState.IsValid) { //Create a use case object to map to, which can then be saved in the DB UseCase uc = new UseCase(); uc.ProjectID = model.ProjectId; uc.ActorID = model.ActorId; uc.Level = (Level)model.Level; db.SaveChanges(); return RedirectToAction("Index", new { id = model.ProjectId }); } return View(model); } ``` ViewModel ``` public class UserGoalsStepViewModel { public enum GoalLevel { Summary, UserGoal, SubGoal, } public int ProjectId { get; set; } public int ActorId { get; set; } [DisplayName("Actor Title")] public SelectList ActorList { get; set; } [DisplayName("Goal Title")] public string GoalTitle { get; set; } public GoalLevel Level { get; set; } public UserGoalsStepViewModel () { } } ``` VIEW ``` @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>UseCase</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.ActorList, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownListFor(model => model.ActorList, Model.ActorList, new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.ActorList, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.GoalTitle, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.GoalTitle, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.GoalTitle, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Level, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EnumDropDownListFor(model => model.Level, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Level, "", 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> } ``` UPDATED POST METHOD WHICH IS STILL GIVING AN ERROR AND NOT SAVING TO DB After amends, I'm now getting this error `Message=The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.UseCase_dbo.Actor_ActorID". The conflict occurred in database "JustSpecIt", table "dbo.Actor", column 'ID'` when attempting to save to DB. Here is relevant bit of updated POST method: ``` if (ModelState.IsValid) { //Create a use case object to map to, which can then be saved in the DB UseCase uc = new UseCase(); uc.ProjectID = model.ProjectId; uc.ActorID = model.ActorId; uc.Title = model.GoalTitle; uc.Level = (Level)model.Level; db.UseCases.Add(uc); db.SaveChanges(); return RedirectToAction("Index", new { id = model.ProjectId }); } ```