razorpropertiesasp.net-mvc-4htmlextensions

Value using HTML extension is different than what it is supposed to be if two models have a property with the same name


Here is my scenario.

  1. Created two Models that have a common property name

    public class SimpleModel1
    {
    // Some Properties
    
    public string Property1 { get; set; }
    
    }
    
    public class SimpleModel2
    {
    // Some Properties
    
    public string Property1 { get; set; } // Same name as Property1 in SimpleModel1
    
    }
    
  2. Used SimpleModel1 in an Action (for e.g. Index) that returns a view that looks like this

    @model MvcApplication2.Models.SimpleModel1
    
    @{
    ViewBag.Title = "Home Page";
    }
    
    @using (Html.BeginForm("Test", "Home", FormMethod.Post))
    {
      <label>Enter something here</label>
       @Html.TextBoxFor(m => m.Property1)
       <button type="submit">Submit</button>
    }
    
  3. Submitted the value to a Test action that takes SimpleModel1 as parameter, does some work, and returns a view that takes in SimpleModel2

    public ActionResult Test(SimpleModel1 model)
    {
        SimpleModel2 newModel = new SimpleModel2();
    
        // Do Something
    
        newModel.Property1 = "Something different than model's Property1";
    
        return View(newModel);
    }
    
  4. The Test.cshtml (view returned by Test action) is as below:

    @model MvcApplication2.Models.SimpleModel2
    
    @{
        ViewBag.Title = "Test";
    }
    
    <h2>Test</h2>
    
     @* Model Propery without using HTML extension*@
     @Model.Property1
    
     @* Model property using HTML extension (Incorrect) *@
    
     @Html.TextBoxFor(m => m.Property1)
     @Html.HiddenFor(m => m.Property1)
     @Html.TextAreaFor(m => m.Property1)
    
      @* Correct Value *@
     <input value="@Model.Property1" />
    

What I expect is that all the values of Property1 would be "Something different than model's Property1" as set in Test Action. But it turns out that the ones that use the Html extension (Html.TextBoxFor, Html.HiddenFor etc) have the Property1 value that was posted to Test Action. For example, if I post "What a surprise" ( the Property1 of SimpleModel1) to Test Action, the value of Property1 of SimpleModel2 is also "What a surprise" no matter what I set it to.

I have no idea what is going on. Looks like a bug to me. Does anyone have any idea?


Solution

  • You will see this behavior when doing a POST because posted data is persisted in ModelState. The value for Property1 will be whatever the value was posted for this property. In order to see your new value you need to include this line of code in your ActionResult Test:

    ModelState.Clear();
    

    As a general rule just remember to include this line in case you are posting data, modifying it and trying to see modified data on the returned view.