0

I have a strange problem here.

In the Model (.cs):

    public long? ContactoAdditionalId { get; set; }
    public long Test1 { get; set; }
    public long? Test2 { get; set; }
    public string Test3 { get; set; }

In the Controller (at the end of the action just before the view):

    [HttpPost]
    [AllowAnonymous]
    public ActionResult Index( Contacto model )
    {
        DoSomeStuff( model, ... );

        (...)

        model.Test1 = model.ContactoAdditionalId.HasValue ? model.ContactoAdditionalId.Value : -1;
        model.Test2 = model.ContactoAdditionalId;
        model.Test3 = model.ContactoAdditionalId.HasValue ? model.ContactoAdditionalId.Value.ToString() : "No value!";
        return View( model );
    }

Finally in the View (.cshtml):

@using MyApp.Models;

@model Contacto

@using ( Html.BeginForm( "Index", "Contacto" ) )
{
    @Html.HiddenFor( model => model.ContactoAdditionalId )
    @Html.HiddenFor( model => model.Test1 )
    @Html.HiddenFor( model => model.Test2 )
    @Html.HiddenFor( model => model.Test3 )
    (...)

As you may have guessed, the ContactoAdditionalId (I left it with the real name, in case THAT is the problem) value is NOT appearing in the View.

When I press F12 in Chrome to open the Developer Tools and inspect the HTML, there is no value for the ContactoAdditionalId, but there ARE values for Test1, Test2 and Test3.

Note that I used a long, a long? and a string to check if the problem was something to do with the types, but all three show value in the HTML.

Of course, the purpose of this hidden field is to get that ContactoAdditionalId back when POST'ing. This way it doesn't work and its model property is null!

I also noticed something strange: if I add in the View, just before the HiddenFor:

@Html.DisplayFor( model => model.ContactoAdditionalId, ... )

It suddenly works and now the hidden field has the value in it!

What is happening here? I ran debug step-to-step in Visual Studio 2017 and when I reached the end of the action code, it started stepping in the cshtml View, so no additional code (as far as I know, at least not our project's code) is being executed after the action and before the view is transformed in HTML.

  • 1
    Could you post your full code from you controller and view? – D-Shih Sep 10 '18 at 13:21
  • 1
    You need to show us more details, but I assume you have a parameter for `ContactoAdditionalId` in the method, in which case its related to `ModelState` (refer [TextBoxFor displaying initial value, not the value updated from code](https://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) for an explanation –  Sep 10 '18 at 13:34
  • That would be a lot of code to copy-paste and I'm worried with NDA violations, but let me check your questions. – Rui Miguel Pinheiro Sep 10 '18 at 13:40
  • I will comment Controller and View code that I think it's not related with the problem and check if the problem continues; if so, there will be less to copy-paste and less NDA worries. – Rui Miguel Pinheiro Sep 10 '18 at 13:41
  • Done. The action method has only the model being passed after POST. But note that the problem occurs in the view after going from action to view. The property is filled in the end of the action (as you can see, it fills with success the Test1, Test2 and Test3) but in the HTML rendered, I see the ContactoAdditionalId is not filled, but Test1, Test2 and Test3 are filled. – Rui Miguel Pinheiro Sep 10 '18 at 13:54
  • I also tried to use other name (e.g. XptoId) and to use long instead of long? (assuming 0 as the null value and changing all the if's in the code). Same problem, and only with that field. I also noticed that sometimes Test* properties are filled and other times, they aren't. Problem seems to be non-deterministic. – Rui Miguel Pinheiro Sep 10 '18 at 14:44
  • @Stephen Muecke, you got me in the right track! ModelState was the problem. – Rui Miguel Pinheiro Sep 10 '18 at 15:13

1 Answers1

1

You probably have a parameter in ModelState with the same name than the one you don't see the data. If you are changing that value in the Model, without clearing it from the ModelState, HiddenFor will pick the ModelState field first. Either do a ModelState.Clear(), or remove only the field with ModelState.Remove( "ContactoAdditionalId" )"

Also, you can use ModelState.Clear().

Ribeiro
  • 364
  • 1
  • 3
  • 12