Force Blank TextBox with ASP.Net MVC Html.TextBox
- by Doug Lampe
I recently ran into a problem with the following scenario:
I have data with a parent/child data with a one-to-many relationship from the parent
to the child.
I want to be able to update parent and existing child data AND add a new
child record all in a single post.
I don't want to create a model just to store the new values.
One of the things I LOVE about MVC is how flexible it
is in dealing with posted data. If you have data that isn't in your model,
you can simply use the non-strongly-typed HTML helper extensions and pass the
data into your actions as parameters or use the FormCollection. I thought
this would give me the solution I was looking for. I simply used Html.TextBox("NewChildKey")
and Html.TextBox("NewChildValue") and added parameters to my action
to take the new values. So here is what my action looked like:
[HttpPost]
public ActionResult EditParent(int? id, string newChildKey,
string newChildValue, FormCollection forms)
{
Model model =
ModelDataHelper.GetModel(id ?? 0);
if (model != null)
{
if (TryUpdateModel(model))
{
if (ModelState.IsValid)
{
model
= ModelDataHelper.UpdateModel(model);
}
string[] keys = forms.GetValues("ChildKey");
string[] values = forms.GetValues("ChildValue");
ModelDataHelper.UpdateChildData(id ?? 0, keys,
values);
ModelDataHelper.AddChildData(id ?? 0, newChildKey, newChildValue);
model =
ModelDataHelper.GetModel(id ?? 0);
}
return View(report);
}
return new EmptyResult();
}
The only problem with this is that MVC is TOO smart. Even though
I am not using a model to store the new child values, MVC still passes the values
back to the text boxes via the model state. The fix for this is simple but
not necessarily obvious, simply remove the data from the model state before returning
the view:
ModelState.Remove("NewChildKey");
ModelState.Remove("NewChildValue");
Two lines of code to save a lot of headaches.