0

I am getting started with Asp.Net MVC. This is in my cshtml:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @class = "form-horizontal" }))
{
    @Html.TextBoxFor(m => m.Username, new { @class = "form-control" })
    <input type="submit" value="Submit" />
}

This is my controller:

 public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";            
            return View();
        }

        [HttpPost]
        public ActionResult Index(TestModel testModel)
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
            testModel.Username = string.Empty;

            return View(testModel);
        }
    }

As you can see when the form is posted I am clearing the Username property to empty yet the old value stays as it. What am I missing?

Jack
  • 7,433
  • 22
  • 63
  • 107
  • Are you sure it is not browser autocomplete ? – fly_ua Jan 08 '15 at 09:17
  • Can you put a breakpoint to your view and see what is the value in your model? – Sefa Jan 08 '15 at 09:18
  • Your index GET view doesn't pass a model, so how would it know what to do with testModel.Username? – markpsmith Jan 08 '15 at 09:18
  • @vgsefa. That is empty but the form shows the value. – Jack Jan 08 '15 at 09:22
  • I have had this issue in the past as well. I can't remember what the reason behind it was, but I think it is by design that a model passed in and back into a view cannot be changed. If the model contains null values they can be, but a value cannot be changed to a null. Creating a new variable and assigning testModel to it might work - try to trick ASP into thinking it is a new variable. – Nigel Ellis Jan 08 '15 at 09:22

2 Answers2

1

I was able to reproduce your issue on my local environment and what you need to do is using the following line inside the post method

ModelState.Clear();

Your method should look like the following

[HttpPost]
public ActionResult Index(TestModel testModel)
{
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
    testModel.Username = string.Empty;
    ModelState.Clear();
    return View(testModel);
}
Hossam Barakat
  • 1,399
  • 9
  • 19
  • 2
    While this is technically correct answer, i would suggest that you reconsider such approach. Having a view returned after a POST request is not considered as a good design pattern. Usually, every POST request should end up with redirect to appropriate GET action. More info [here](http://en.wikipedia.org/wiki/Post/Redirect/Get). – ljubomir Jan 08 '15 at 09:48
  • 1
    The last part of [this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) explains the _Why_ –  Jan 08 '15 at 10:03
  • @ljubomir: But what to when there is some validation server side and it is incorrect. I can't empty out the whole form just because 1 validation failed. Please suggest. A redirect would mean emptying out whole form which I don't want. – Jack Jan 08 '15 at 10:11
  • @Jack you are correct - in case of failed validation the action should return the view with the validation errors displayed. In that case you are not going to perform any transactional action on the application state so it is safe to return the same view. – ljubomir Jan 08 '15 at 13:06
-1

It doesn't seem you have let the view know which model it should work with. Do you have

@Model TestModel

somewhere at the top of your view but forgot to copy here?

Daniel