为什么POST动作会丢失模型值?

时间:2014-11-26 17:43:26

标签: c# asp.net-mvc

我有一个ViewModel,我试图回发以保存在数据库中。当ViewModel获取//GET Create(int id)中设置的值时,它会在到达//POST Create ()时丢失其中一些值。 GoalLevelGoalTitle正在通过确定,但ActorIdProjectId正在丢失,即使调试器正在通过if (Model.State.IsValid)块,正在经历的值未保存到DB。然后重定向会失败,因为我不再有有效的ProjectId传递给URL。

如果你知道自己在做什么,我相信这是显而易见的事情。

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);
    }           

视图模型

 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 ()
            {

            }


    }

查看

@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>
}

更新的帖子方法仍然存在错误而不能保存到数据库

在修复之后,我现在在尝试保存到数据库时收到此错误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'

以下是更新的POST方法的相关内容:

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 });
            }

1 个答案:

答案 0 :(得分:5)

您需要将ProjectId和ActorId的值存储为表单上的隐藏输入,以便它们可以包含在发送回控制器操作的发布值中。

 @using (Html.BeginForm()) 
 {
     @Html.AntiForgeryToken()
     @Html.HiddenFor(x => x.ProjectId)
     @Html.HiddenFor(x => x.ActorId)
     ...
 }