0

For an example, I am creating an ASP.Net MVC controller for the following model:

public class MyItem
{
    public int ID { get; set; }
    public int ItemTypeID { get; set; }
    public string Description { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime? ModifyDate { get; set; }
}

For this example, Description is the only field the user will be able to see or modify.

I set ItemTypeID and CreateDate when the record is first created.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(
    Include = "ID,ItemTypeID,Description,CreateDate,ModifyDate")] MyItem myItem)
{
    if (ModelState.IsValid)
    {
        // Set values for behind-the-scenes columns.
        myItem.ItemTypeID = 1;
        myItem.CreateDate = DateTime.Now;

        db.MyItems.Add(myItem);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(myItem);
}

My Edit view only has a control for Description, since that's the only one I'll need on the form.

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

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

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

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

My HttPost Edit function sets the ModifyDate.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(
    Include = "ID,ItemTypeID,Description,CreateDate,ModifyDate")] MyItem myItem)
{
    if (ModelState.IsValid)
    {
        // Set modified date.
        myItem.ModifyDate = DateTime.Now;

        db.Entry(myItem).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(myItem);
}

My problem is when it executes the HttpPost Edit, the ItemTypeID and CreateDate are cleared out on the object it sends, since I don't include them on the view. Will my Edit forms need hidden fields for every unused column, or is there a better way to carry over those values?

Pizzor2000
  • 379
  • 3
  • 19
  • what is the version of your EF ? – Ganesh Vellanki Sep 26 '17 at 13:36
  • Your editng data so always use a view model containing only those properties needed in the view. In the POST method, you get the data model based on is ID and update only the properties needed - [What is ViewModel in MVC?](https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Sep 26 '17 at 13:37
  • @GaneshVellanki I'm using EF v 6.1.3. – Pizzor2000 Sep 26 '17 at 13:50
  • @StephenMuecke I'll look into the ViewModel idea. – Pizzor2000 Sep 26 '17 at 13:50

1 Answers1

0

Will my Edit forms need hidden fields for every unused column

No, but it will need fields for any used value. This would include any value you need to be included in the model when it's sent back to the server. (It's also of course worth noting that any value sent to the server can be modified by the user, and user input shouldn't be implicitly trusted for any security or authorization purposes.)

Essentially you have two options:

  1. Include in the form POST any values needed to re-construct your object.
  2. Include in the form POST an identifier to refer to your object, and use that identifier to fetch the object from the data and re-construct it from that.

The latter approach may indeed work for you, since you already include the identifier in the form:

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

You can use that to fetch the actual model instance from the database, then use the subset of form data you do receive to change relevant values on that model instance.

David
  • 208,112
  • 36
  • 198
  • 279