user357086
user357086

Reputation: 404

Rendering hidden form field using @Html.HiddenFor

public class SearchForm {

     //Note: Property is nullable 
     public DateTime? CurrentViewDate {get;set;}       
     public DateTime  StartDate {get;set;}
}

//In the controller     
//[GET] 
public ActionResult Index()
{
}

//[POST]    
public ActionResult Index(SearchForm formModel)
{
     if(formModel.CurrentViewDate == null)            
        formModel.CurrentViewDate = DateTime.Now.AddDays(1d);
     else
        formModel.CurrentViewDate = formModel.CurrentViewDate.AddDays(1d);

    formModel.StartDate = DateTime.Now;   

}


//In view
@Html.HiddenFor(c => c.CurrentViewDate).
<input id="SearchForm_CurrentViewDate" name="SearchForm.CurrentViewDate" 
       type="hidden" value="5/25/2012 11:59:59 PM" />
<input type="submit" name="btnNext" id="btnNext" value="Go Increment" />

But, I when click submit the value does gets incremented but the hidden for field holds the previous value and the only way it displays correct value is If do this @Html.HiddenFor(c => c.CurrentViewDate.Value) , but then on the re-post the formModel.CurrentViewDate has null value since the binding names are different.

Any ideas? It feels like it fetches the date time value from StartDate property instead of CurrentViewDate property

Upvotes: 1

Views: 1149

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

You need to remove the value from the ModelState if you intend to modify it:

public ActionResult Index(SearchForm formModel)
{
    ModelState.Remove("CurrentViewDate");

    if(formModel.CurrentViewDate == null)            
    {
        formModel.CurrentViewDate = DateTime.Now.AddDays(1d);
    }
    else
    {
        formModel.CurrentViewDate = formModel.CurrentViewDate.AddDays(1d);
    }

    return View(model);
}

The reason you need to do this is because all Html helpers such as TextBoxFor, HiddenFor, CheckBoxFor, ... first look in the ModelState when binding their values and after that they look in the model. This behavior is by design. So since in your POST action there's already a value in the ModelState (the one that was sent with the request) it is this value that's being used.

Everytime you attempt to modify some property on your view model inside a POST controller action and expect this change to reflect in the value don't forget about the ModelState.

Upvotes: 2

Related Questions