BviLLe_Kid BviLLe_Kid - 2 months ago 11
C# Question

My ID field is getting a value when it shouldn't be

In my

[HttpGet] Create Action
I have this:

public ActionResult Create(int? id)
{
ViewBag.TestTypeID = new SelectList(db.codeTypes, "ID", "TestType");

OHealth oHealth = new OHealth();
oHealth.OID = Convert.ToInt32(id);

oHealth.DateEntered = DateTime.Today;

return View(oHealth);
}


Now,
OID
is a foreign key, not the primary key
ID
. As you can see I don't assign
ID
any value.. only
OID
.
ID
is auto-incremented in the database.

Here is how my HTML renders for my Create View for
OID
and
ID
:

<input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="2" />
<input data-val="true" data-val-number="The field OID must be a number." data-val-required="The OID field is required." id="OID" name="OID" type="hidden" value="2" />


So when I hit create, the
ID
field is given the value of
2
when it should be
1
since it will be the first record in the database.

How is my
ID
field receiving a value of
2
when that hasn't been assigned?

Let me know if more is needed.

Any help is appreciated.

UPDATE

Razor for those 2 fields:

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

Answer

MVC automatically binds parameters into the modelstate. So your parameter id in:

public ActionResult Create(int? id)

will be automatically put into Model.ID (as url params are case-insensitive).

You should be able to confirm this by changing the name of the parameter (and corresponding url/action definition), eg:

public ActionResult Create(int? anotherid) 

and change the url from /Create/2 to /Create?anotherid=2

This occurs automatically so that any values in a POST will automatically have the same values they had when the form was posted without you needing to explicitly set them. In a GET this occurs from the parameters.

The fix is to add ModelState.Clear():

public ActionResult Create(int? id) 
{
    if (!ModelState.IsValid) return;

    ModelState.Clear();

this will stop the auto-rebinding when the view fields are regenerated.

The re-binding occurs after the view has been generated, all the field values are re-inserted from ModelState. By clearing modelstate, you stop this from happening.