4

In my UploadFilesViewModel I have a property:

[HiddenInput(DisplayValue = false)]
public bool DirBlocked { get; set; }

and in my view, the following markup for it:

@Html.HiddenFor(m => m.DirBlocked)

When I execute the following code in my GET action:

var model = new UploadFilesViewModel { UserBaseDir = await GetUserBaseDirAsync() };
model.DirBlocked = true;
return View(model);

The hidden input for DirBlocked renders as follows:

<input data-val="true" data-val-required="The DirBlocked field is required." id="DirBlocked" name="DirBlocked" type="hidden" value="True">

Yet when I execute the following code in the POST action:

// Hard 'true' just for debugging.
//if (files.Any() && !HasDirAccess(model.UploadDir))
if (true)
{
    model.DirBlocked = true;
    return View(model);
}

The same hidden input renders as follows:

<input data-val="true" data-val-required="The DirBlocked field is required." id="DirBlocked" name="DirBlocked" type="hidden" value="False"> 

That is, it loses the true value assigned to the DirBlocked property. What could be causing this? Normally when I do a return View(model) in a POST action all model properties are rendered correctly, as they are set.

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • 1
    Are you posting your model? I take it, model.DirBlocked should be posted back to the sever with value = true, right? Why do you need to reset it to true? – Hooman Bahreini Apr 25 '18 at 05:07
  • @Sarhang Why I set it to `true` is because if a value in the posted model is equal to another value, I need to re-display the view and execute some client code. – ProfK Apr 25 '18 at 05:18
  • 1
    Refer [this answer](https://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) to understand the behavior –  Apr 25 '18 at 05:19

2 Answers2

2

When re-displaying a posted page, the Html Helper-methods will first look for the posted value to re-display the form. If they can't find a value, they will take it from the model object instead. What you can do to prevent that is to clear the ModelState before doing a return:

model.DirBlocked = true;
ModelState.Clear(); 
return View(model);

That will, however, clear the form of any user-entered data not passed back to the view, and it will also clear any validation messages. See https://msdn.microsoft.com/en-us/library/system.web.mvc.modelstatedictionary.aspx for more information about the ModelState.

JLe
  • 2,835
  • 3
  • 17
  • 30
2

Actually the HtmlHelper does not use Model but ModelState. You can solve this by avoiding the html helper and using the model field directly.

Sentinel
  • 3,582
  • 1
  • 30
  • 44