Hiddenfor not getting correct value from view model












43















I have a multi-step file import process. I have a hidden form input in my view that I am trying to populate with the "CurrentStep" from the view model.



<% = Html.HiddenFor(model => model.CurrentStep) %>


CurrentStep is an Enum and I always get the default value rather than the one I provided to the view model. on the other hand this gets me the correct value:



<p><% = Model.CurrentStep %></p>


I realise I could just hand code the hidden input but I want to know: what am I doing wrong? Is there a better way to keep track of the current step between POSTs?










share|improve this question

























  • Show us the code for your form (such as Html.BeginForm()), please.

    – Serge Wautier
    Jan 29 '11 at 15:50
















43















I have a multi-step file import process. I have a hidden form input in my view that I am trying to populate with the "CurrentStep" from the view model.



<% = Html.HiddenFor(model => model.CurrentStep) %>


CurrentStep is an Enum and I always get the default value rather than the one I provided to the view model. on the other hand this gets me the correct value:



<p><% = Model.CurrentStep %></p>


I realise I could just hand code the hidden input but I want to know: what am I doing wrong? Is there a better way to keep track of the current step between POSTs?










share|improve this question

























  • Show us the code for your form (such as Html.BeginForm()), please.

    – Serge Wautier
    Jan 29 '11 at 15:50














43












43








43


12






I have a multi-step file import process. I have a hidden form input in my view that I am trying to populate with the "CurrentStep" from the view model.



<% = Html.HiddenFor(model => model.CurrentStep) %>


CurrentStep is an Enum and I always get the default value rather than the one I provided to the view model. on the other hand this gets me the correct value:



<p><% = Model.CurrentStep %></p>


I realise I could just hand code the hidden input but I want to know: what am I doing wrong? Is there a better way to keep track of the current step between POSTs?










share|improve this question
















I have a multi-step file import process. I have a hidden form input in my view that I am trying to populate with the "CurrentStep" from the view model.



<% = Html.HiddenFor(model => model.CurrentStep) %>


CurrentStep is an Enum and I always get the default value rather than the one I provided to the view model. on the other hand this gets me the correct value:



<p><% = Model.CurrentStep %></p>


I realise I could just hand code the hidden input but I want to know: what am I doing wrong? Is there a better way to keep track of the current step between POSTs?







asp.net-mvc






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 5:16









Kiquenet

7,12727110199




7,12727110199










asked Jan 29 '11 at 15:47









user427875user427875

3701515




3701515













  • Show us the code for your form (such as Html.BeginForm()), please.

    – Serge Wautier
    Jan 29 '11 at 15:50



















  • Show us the code for your form (such as Html.BeginForm()), please.

    – Serge Wautier
    Jan 29 '11 at 15:50

















Show us the code for your form (such as Html.BeginForm()), please.

– Serge Wautier
Jan 29 '11 at 15:50





Show us the code for your form (such as Html.BeginForm()), please.

– Serge Wautier
Jan 29 '11 at 15:50












3 Answers
3






active

oldest

votes


















71














What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:



[HttpPost]
public ActionResult Foo(SomeModel model)
{
model.CurrentStep = Steps.SomeNewValue;
return View(model);
}


and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.



So you have a couple of possibilities:





  1. Remove the value from the modelstate:



    [HttpPost]
    public ActionResult Foo(SomeModel model)
    {
    ModelState.Remove("CurrentStep");
    model.CurrentStep = Steps.SomeNewValue;
    return View(model);
    }



  2. Manually generate the hidden field



    <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />


  3. Write a custom helper which will use the value of your model and not the one that's being POSTed







share|improve this answer



















  • 2





    Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

    – user427875
    Jan 29 '11 at 23:38






  • 4





    Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

    – tkerwood
    Jun 29 '11 at 4:03






  • 2





    @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

    – Garth Marenghi
    Aug 2 '12 at 8:56






  • 2





    Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

    – Darin Dimitrov
    Aug 2 '12 at 15:43






  • 10





    @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

    – Paul Fleming
    Aug 25 '12 at 14:56



















6














My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.



<input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />



Just a reminder that you can use Html.NameFor to keep things clean.






share|improve this answer































    0














    Make sure you model property has a "set" operator.



    This won't get updated on post-back:



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



    public Class MyModel
    {
    int _NoSeq;
    public NoSeq
    {
    get { return _NoSeq };
    }
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4837744%2fhiddenfor-not-getting-correct-value-from-view-model%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      71














      What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:



      [HttpPost]
      public ActionResult Foo(SomeModel model)
      {
      model.CurrentStep = Steps.SomeNewValue;
      return View(model);
      }


      and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.



      So you have a couple of possibilities:





      1. Remove the value from the modelstate:



        [HttpPost]
        public ActionResult Foo(SomeModel model)
        {
        ModelState.Remove("CurrentStep");
        model.CurrentStep = Steps.SomeNewValue;
        return View(model);
        }



      2. Manually generate the hidden field



        <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />


      3. Write a custom helper which will use the value of your model and not the one that's being POSTed







      share|improve this answer



















      • 2





        Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

        – user427875
        Jan 29 '11 at 23:38






      • 4





        Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

        – tkerwood
        Jun 29 '11 at 4:03






      • 2





        @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

        – Garth Marenghi
        Aug 2 '12 at 8:56






      • 2





        Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

        – Darin Dimitrov
        Aug 2 '12 at 15:43






      • 10





        @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

        – Paul Fleming
        Aug 25 '12 at 14:56
















      71














      What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:



      [HttpPost]
      public ActionResult Foo(SomeModel model)
      {
      model.CurrentStep = Steps.SomeNewValue;
      return View(model);
      }


      and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.



      So you have a couple of possibilities:





      1. Remove the value from the modelstate:



        [HttpPost]
        public ActionResult Foo(SomeModel model)
        {
        ModelState.Remove("CurrentStep");
        model.CurrentStep = Steps.SomeNewValue;
        return View(model);
        }



      2. Manually generate the hidden field



        <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />


      3. Write a custom helper which will use the value of your model and not the one that's being POSTed







      share|improve this answer



















      • 2





        Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

        – user427875
        Jan 29 '11 at 23:38






      • 4





        Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

        – tkerwood
        Jun 29 '11 at 4:03






      • 2





        @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

        – Garth Marenghi
        Aug 2 '12 at 8:56






      • 2





        Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

        – Darin Dimitrov
        Aug 2 '12 at 15:43






      • 10





        @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

        – Paul Fleming
        Aug 25 '12 at 14:56














      71












      71








      71







      What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:



      [HttpPost]
      public ActionResult Foo(SomeModel model)
      {
      model.CurrentStep = Steps.SomeNewValue;
      return View(model);
      }


      and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.



      So you have a couple of possibilities:





      1. Remove the value from the modelstate:



        [HttpPost]
        public ActionResult Foo(SomeModel model)
        {
        ModelState.Remove("CurrentStep");
        model.CurrentStep = Steps.SomeNewValue;
        return View(model);
        }



      2. Manually generate the hidden field



        <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />


      3. Write a custom helper which will use the value of your model and not the one that's being POSTed







      share|improve this answer













      What you are doing wrong is that you are trying to modify the value of a POSTed variable in your controller action. So I suppose you are trying to do this:



      [HttpPost]
      public ActionResult Foo(SomeModel model)
      {
      model.CurrentStep = Steps.SomeNewValue;
      return View(model);
      }


      and html helpers such as HiddenFor will always first use the POSTed value and after that the value in the model.



      So you have a couple of possibilities:





      1. Remove the value from the modelstate:



        [HttpPost]
        public ActionResult Foo(SomeModel model)
        {
        ModelState.Remove("CurrentStep");
        model.CurrentStep = Steps.SomeNewValue;
        return View(model);
        }



      2. Manually generate the hidden field



        <input type="hidden" name="NextStep" value="<%= Model.CurrentStep %>" />


      3. Write a custom helper which will use the value of your model and not the one that's being POSTed








      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jan 29 '11 at 16:36









      Darin DimitrovDarin Dimitrov

      848k22330262750




      848k22330262750








      • 2





        Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

        – user427875
        Jan 29 '11 at 23:38






      • 4





        Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

        – tkerwood
        Jun 29 '11 at 4:03






      • 2





        @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

        – Garth Marenghi
        Aug 2 '12 at 8:56






      • 2





        Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

        – Darin Dimitrov
        Aug 2 '12 at 15:43






      • 10





        @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

        – Paul Fleming
        Aug 25 '12 at 14:56














      • 2





        Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

        – user427875
        Jan 29 '11 at 23:38






      • 4





        Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

        – tkerwood
        Jun 29 '11 at 4:03






      • 2





        @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

        – Garth Marenghi
        Aug 2 '12 at 8:56






      • 2





        Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

        – Darin Dimitrov
        Aug 2 '12 at 15:43






      • 10





        @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

        – Paul Fleming
        Aug 25 '12 at 14:56








      2




      2





      Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

      – user427875
      Jan 29 '11 at 23:38





      Thanks. I thought the whole point of a view model was to pass complex (more complex than should be contained in ViewData at least) information to the View. So the View isn't using the View Model I'm passing to it? It's just getting whatever was in the POST vars? That doesn't make much sense to me.

      – user427875
      Jan 29 '11 at 23:38




      4




      4





      Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

      – tkerwood
      Jun 29 '11 at 4:03





      Thanks, great answer. For (1) you can also use ModelState.Clear() to remove all values.

      – tkerwood
      Jun 29 '11 at 4:03




      2




      2





      @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

      – Garth Marenghi
      Aug 2 '12 at 8:56





      @Darin Dimitrov: we had a similar problem, and your post helped us a lot. But what we do not get, and maybe you have the answer, is WHY it does this. Why does it take the value from the POST, even though you seemingly override it with the value from the model in the .cshtml.

      – Garth Marenghi
      Aug 2 '12 at 8:56




      2




      2





      Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

      – Darin Dimitrov
      Aug 2 '12 at 15:43





      Because that's the behavior a user will want in 99.99% of the cases: he will want to see the same values that he entered in the form after postback, not some new value that you assigned in the POST action. Just imagine that a user types some value into a textbox, then some model error occurs and you modify this value and redisplay the form. The user might not pay attention that the value he entered was modified. That's the reason why this is the default behavior: because you are not supposed to modify what the user sent you to the POST action in most cases.

      – Darin Dimitrov
      Aug 2 '12 at 15:43




      10




      10





      @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

      – Paul Fleming
      Aug 25 '12 at 14:56





      @DarinDimitrov. Surely this is not for MS to decide. If I change the posted value, I am doing so deliberately. Why does MVC need to override my preference? What benefit does this feature have? Apologies if I'm overlooking something really obvious!

      – Paul Fleming
      Aug 25 '12 at 14:56













      6














      My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.



      <input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />



      Just a reminder that you can use Html.NameFor to keep things clean.






      share|improve this answer




























        6














        My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.



        <input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />



        Just a reminder that you can use Html.NameFor to keep things clean.






        share|improve this answer


























          6












          6








          6







          My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.



          <input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />



          Just a reminder that you can use Html.NameFor to keep things clean.






          share|improve this answer













          My solution was to use Darin's second option, because option 1 (clearing from the model state) means hard coding a string (and the naming convention can be tricky with complex models), and wanted to avoid option 3 because I already have so many custom helpers.



          <input type="hidden" name="@Html.NameFor(x => Model.SomeId)" value="@Model.SomeId" />



          Just a reminder that you can use Html.NameFor to keep things clean.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 14 '15 at 17:06









          ZacZac

          1,13011521




          1,13011521























              0














              Make sure you model property has a "set" operator.



              This won't get updated on post-back:



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



              public Class MyModel
              {
              int _NoSeq;
              public NoSeq
              {
              get { return _NoSeq };
              }
              }





              share|improve this answer




























                0














                Make sure you model property has a "set" operator.



                This won't get updated on post-back:



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



                public Class MyModel
                {
                int _NoSeq;
                public NoSeq
                {
                get { return _NoSeq };
                }
                }





                share|improve this answer


























                  0












                  0








                  0







                  Make sure you model property has a "set" operator.



                  This won't get updated on post-back:



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



                  public Class MyModel
                  {
                  int _NoSeq;
                  public NoSeq
                  {
                  get { return _NoSeq };
                  }
                  }





                  share|improve this answer













                  Make sure you model property has a "set" operator.



                  This won't get updated on post-back:



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



                  public Class MyModel
                  {
                  int _NoSeq;
                  public NoSeq
                  {
                  get { return _NoSeq };
                  }
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 23 '18 at 18:17









                  ReBoot The UniverseReBoot The Universe

                  588




                  588






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4837744%2fhiddenfor-not-getting-correct-value-from-view-model%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                      Alcedinidae

                      Origin of the phrase “under your belt”?