1

I have a Model property which the controller sets to 1 but in my view I see it as 0 and 1 depending on how I access it.

View snippet (these lines are absolutely consecutive too!)

@Html.DisplayFor(model => model.resumeStage)    
@Html.HiddenFor(model => model.resumeStage)
@Html.EditorFor(model => model.resumeStage)

Rendered HTML (I moved the value= at the front of the tag for readability)

1
<input value="0" data-val="true" data-val-number="The field resumeStage must be a number." data-val-required="The resumeStage field is required." id="resumeStage" name="resumeStage" type="hidden" />
<input value="0" class="text-box single-line" id="resumeStage" name="resumeStage" type="number" />

Shouldn't the value always be 1? I seem to lose the state of that property when I present it inside a text box! The views-controllers are strong bound by the model class which is defined as

public class CreateUserModel
{
    [Required]
    public int resumeStage { get; set; } // <== problem

    public LocalProfile newLocalUser { get; set; }
    public ExtProfile newExtUser { get; set; }

    public CreateUserModel()
    {
        resumeStage = 0;
        newLocalUser = new LocalProfile();
        newExtUser = new ExtProfile();
        preFillWithTestData();
    }

    private void preFillWithTestData()
    {
        // prefill the newLocalUser
        // and newExtUser classes with dummy data
    }
}

The controller method receiving the form POST (where I flip the int from 0=>1) is :

[HttpPost]
public ActionResult UserRegistration(CreateUserModel newUser)
{
    try
    {
        //stage 0, setup local account
        if (newUser.resumeStage <= 0)
        {
            // do stuff
            newUser.resumeStage = 1;
        }

        // stage 1, setup external account
        if (newUser.resumeStage <= 1)
        {
            // test an exception
            Exception ex = new Exception("TEST: External service provider offline");
            throw ex;
            newUser.resumeStage = 2;
        }

        return RedirectToAction("Index");
    }
    catch (Exception ex)
    {
        return View(newUser); // newUser.resumeStage is 1 here but 
                              // view will disagree
    }
}

The controller method creating and presenting the form is:

public ActionResult UserRegistration()
{
    // Constructor prefills with test data, nothing more to do
    CreateUserModel newUser = new CreateUserModel();

    return View(newUser);
}

Question: Does anyone know why I cannot seem to have resumeStage shown as 1 inside the HTML rendered Textbox?

tereško
  • 58,060
  • 25
  • 98
  • 150
DeepSpace101
  • 13,110
  • 9
  • 77
  • 127

1 Answers1

1

You should add ModelState.Remove("resumeStage"); or add a call to ModelState.Clear();

catch (Exception ex)
{
    ModelState.Remove("resumeStage");
    return View(newUser); // newUser.resumeStage is 1 here but 
                          // view will disagree
}
Yannick Blondeau
  • 9,465
  • 8
  • 52
  • 74
ChunHao Tang
  • 554
  • 3
  • 9
  • 1
    Found the reason at http://stackoverflow.com/questions/1775170/asp-net-mvc-modelstate-clear ... it's a VERY weird MVC behavior! – DeepSpace101 Oct 29 '12 at 06:40