Reputation: 33
I am trying to learn MVC3. I have used TextBoxFor HTML helper control to persist the value over multiple post backs.
Surprisingly the value is persisting, but not reflecting in the view.
My Model class looks like this :
public class FileViewModel
{
public string FileName { get; set; }
public string ValidationMsg { get; set; }
}
My Actions methods in controller looks something like this :
public ActionResult DemoFormElements()
{
return View();
}
[HttpPost]
public ActionResult DemoFormElements(FileViewModel fVM)
{
fVM.FileName = "Overridden Text" + fVM.FileName ;
return View(fVM);
}
My View looks like this :
@using (@Html.BeginForm())
{
if (Model != null)
{
@Html.LabelFor(b => b.FileName)
@Html.TextBoxFor(n => n.FileName, Model.FileName)
}
else
{
@Html.LabelFor(b => b.FileName)
@Html.TextBoxFor(n => n.FileName)
}
<input type="submit" id="SubmitBtn" value="Ok" />
}
When I post back by clicking the OK button, I am able to get the value what I entered in the textbox, but in the controller I am trying to append that value to "Hi" & expecting the appended value in my view, which is not happening...
I am seeing the value of the control is persisting (whatever I ve entered), but not changing :( Please help me with giving some clue if its an expected behavior or I m doing any mistake here?
Upvotes: 3
Views: 1444
Reputation: 2588
The straight forward solutions to your problem could be:
In controller Post method, use ModelState.Remove("[Mode's Property Name]") before it is assigned new value with the Controller. Here it should be : ModelState.Remove("FileName");
Or Use ModelState.Clear(): this forces the page to forget all previous values & clears all the previous entries.
Or on the view page, change Html.TextBoxFor() to Html.TextBox() for the particular model property.
Or use PRG pattern : (Post-Redirect-Get pattern) as suggested by Craig above.
Choose one among these alternative solutions which fits to your need.
Upvotes: 2
Reputation: 2236
I would return a viewModel for the get action
public ActionResult Index()
{
return View(new FileViewModel());
}
I would simplify the view to this
<span>@Model.FileName</span>
@using (@Html.BeginForm())
{
@Html.LabelFor(m => m.FileName)
@Html.TextBoxFor(m => m.FileName)
<input type="submit" id="SubmitBtn" value="Ok" />
}
Please also read this MVC2 TextBoxFor value not updating after submit?
Upvotes: 0
Reputation: 18155
There are a couple of problems with this. You can't overwrite the values in the model during a postback because MVC will override that and retain the old values in order to redisplay them in the case of an error. You also should not, generally speaking, be returning a view from the POST handler, you should use a PRG (Post - Redirect - Get) pattern. That's done so that if the user clicks Refresh in their browser it doesn't POST again. So, having said all that, I would change the controller as follows:
public ActionResult DemoFormElements()
{
var viewModel = new FileViewModel();
if( TempData.ContainsKey( "UpdatedFilename" )
{
viewModel = TempData["UpdatedFilename"];
}
return View( viewModel );
}
[HttpPost]
public ActionResult DemoFormElements(FileViewModel fVM)
{
TempData["UpdatedFilename"] = "Overridden Text" + fVM.FileName;
return RedirectToAction( "DemoFormElements" );
}
This will also simplify your View because you don't have to do that null check for model, you will always have a model.
@using (@Html.BeginForm())
{
@Html.LabelFor(model => model.FileName)
@Html.TextBoxFor(model => model.FileName)
<input type="submit" id="SubmitBtn" value="Ok" />
}
Upvotes: 2