MVC: Why is my Edit controller method not receivin

2019-08-06 11:24发布

问题:

I am using MVC to create standard create / edit forms for my ViewModel. I have my create working great, now I'm onto my edit form, and the ViewModel's ID is being passed as 0, even though I can see the DOM Element explorer (& web UI) that ID is set to 10004. I tried binding all the fields to my [HttpPost] Edit controller method, but the ID remains 0. Any ideas?

Here's a snippet of my code (I have too many fields, etc to post everything, and all other fields are coming across correctly).

Thanks in advance!

ViewModel

public class Header_VM
    {           
        [DisplayName("Contract ID")]
        public int Contract_Key { get; set; }

        etc
    }

View

@model (root).Header.Header_VM

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit Header: @Model.Name</h2>

@using (Html.BeginForm("Edit", "Header", FormMethod.Post, new { name = "EditForm" }))
{
    @Html.AntiForgeryToken()

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

        <div class="form-group">
            @Html.LabelFor(model => model.Contract_Key, htmlAttributes: new { @class = "control-label col-md-2" })
            @Html.DisplayFor(model => model.Contract_Key)
        </div>
        etc...
    </div>
}

I have a break point on "int NewID...", and at that point Contract_Key is 0.

Controller

[HttpPost]
public ActionResult Edit([Bind(Include = "Contract_Key, etc...")] Header_VM header)
{
     int NewID = DB.Header_Insert(header);
     return RedirectToAction("Details", "Header", new { Contract_Key = NewID });
 }

回答1:

The DisplayFor helper method generates HTML markup to display the property value. So if you inspect the page source(view source), you will see markup for a label tag for the Contract_Key property. When you submit the form, only input form field values are submitted , not label/div values

You need an input form field inside your form with name attribute value set to "Contract_Key".

You can use the HiddenFor helper method, which generates a hidden input element with the name attribute value matching to the property name.

 @Html.DisplayFor(model => model.Contract_Key)
 @Html.HiddenFor(model => model.Contract_Key)

Or simply a hand written hidden input

<input type="hidden" name="Contract_Key" value="@Model.Contract_Key" />