Reputation: 16120
I have an action that basically does this:
public ViewResult Save(Foo postedFoo)
{
Foo foo;
if (postedFoo.Id == 0) //New foo; need to save for first time
{
foo = new Foo();
}
else //Already exists, need to load and update
{
foo = FooRepository.LoadFoo(postedFoo.Id);
}
UpdateModel(foo);
FooRepository.Save(foo);
return View(foo);
}
As you can see, the action handles both creating new Foo
instances and updating existing ones.
The Foo's Id property is written into a hidden field in the view like this:
@Html.HiddenFor(m => m.Id)
The problem is that in the scenario where the user saves a new Foo
, the Foo
's Id
property (which is being set in the line FooRepository.Save(foo)
) is NOT being written to the hidden field before the page is redisplayed to the user.
This means that if the user saves a new Foo
, then immediately changes something and saves again, the controller thinks it's another new Foo
and creates a new Foo
in the database rather than just updating it.
Can anyone suggest why the hidden field is not being populated?
Upvotes: 1
Views: 172
Reputation: 12437
shouldn't the else
line read
foo = FooRepository.LoadFoo(postedFoo.Id);
Also, the new Foo();
isn't setting the value of ID
anywhere unless you've hardcoded it into your model.
But if FooRepository.Save(foo)
is meant to do this, it's not. You need to return the ID
field back to your controller.
foo = FooRepository.Save(foo);
Upvotes: 0
Reputation: 39501
Write
ModelState.Remove("Id")
Before returning View();
This behavior is caused by the fact that ModelState
is the primary supplier for values when rendering (yes, not the Model
itself). So removing Id from ModelState
, makes editors use Model
's value (In your case, updated Id
)
Upvotes: 2