简体   繁体   中英

Object edited in view delivered by HttpGet Edit() is not received by HttpPost Edit()

I have two edit Action methods, one for HttpGet and one for HttpPost. The HttpGet method takes an id parameter, retrieves the appropriate object, and displays it for editing. The HttpPost method takes a parameter that should be the edited object; however, the ids do not match. Why is that mismatch occurring? I've included the code for my Edit.cshtml view, and for my two Action Methods.

The View:

@model WebApplicationPbiBoard.Models.Sprint

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Sprint</legend>

        @Html.HiddenFor(model => model.Id)

        <div class="editor-label">
            @Html.LabelFor(model => model.Start)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Start)
            @Html.ValidationMessageFor(model => model.Start)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.End)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.End)
            @Html.ValidationMessageFor(model => model.End)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

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

The Action Methods:

 //
        // GET: /Sprint/Edit/5

        public ActionResult Edit(int id)
        {
            var sprint = Db.GetById(id);
            return View(sprint);
        }

        //
        // POST: /Sprint/Edit/5

        [HttpPost]
        public ActionResult Edit(Sprint editedSprint)
        {
            if (ModelState.IsValid)
            {
                Db.Save(editedSprint);
                return RedirectToAction("Index");
            }
            else
                return View(editedSprint);            
        }

Here's the GetById method. It's pretty much a wrapper around the NHibernate ISession.GetById method.

public T GetById(int id)
        {
            return Session.Get<T>(id);
        }

Here's my solution. Thanks to everyone who helped me with debugging it.

The problem was that, to adhere to NHibernate best practices, the setter for my id property was private. That meant that the controller couldn't set it in the reconstructed model object, so the id was the default value of 0. To solve the problem, I passed the id in as a parameter to the controller and found the right object in my repository, which I then manually updated. Here's the code:

[HttpPost]
public ActionResult Edit(int id, DateTime start, DateTime end)
{
    //get the right model to edit
    var sprintToEdit = Db.GetById(id);

    //copy the changed fields
    sprintToEdit.Start = start;
    sprintToEdit.End = end;

    if (ModelState.IsValid)
    {
        Db.Save(sprintToEdit);
        return RedirectToAction("Index");
    }

    else
        return View(sprintToEdit);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM