MVC3 Html.HiddenFor(Model => Model.Id) not passing back to Controller

18,744
public virtual int Id { get; protected set; }

protected set; <!-- That's your problem. You need a public setter if you want the default model binder to be able to assign the value.

Share:
18,744
Darbio
Author by

Darbio

'Senior Enterprise Acrhitect' at the NSW Rural Fire Service, Australia

Updated on June 10, 2022

Comments

  • Darbio
    Darbio almost 2 years

    I have created a strongly typed MVC3 Razor view using the scaffolding code.

    The model is a POCO with a base type of PersistentEntity which defines a property called Created, Updated and Id.

    Id is an int, Created and Updated are DateTime.

    I am using Html.HiddenFor to create the hidden field on the view.

    @Html.HiddenFor(model => model.Id)
    @Html.HiddenFor(model => model.Created)
    @Html.HiddenFor(model => model.Updated)
    

    On the page, the hidden input is being rendered properly, with the Id being set in the value.

    <input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id" type="hidden" value="12">
    

    However when the page is submitted to the controller [HttpPost]Edit(Model model) the Id property is always 0. Created and Updated are correctly populated with the values from the View.

    enter image description here

    This should be 12 in the case of the example in this post. What is going wrong?


    I am aware that I can change the method signature to [HttpPost]Edit(int personID, Person model) as the personID is in the get string, however why does the model not get populated with the hidden field?


    Update

    The problem was that the setter on PersistentEntity was protected, ASP could not set the property, and swallowed it. Changing this to public has solved the problem.

    public abstract class PersistentEntity
    {
        public virtual int Id { get; protected set; }
        public virtual DateTime Created { get; set; }
        public virtual DateTime Updated { get; set; }
    }
    
    • Dabblernl
      Dabblernl over 12 years
      This should work. Have you checked the contructor and the property setter for Id in your class?
    • Giedrius
      Giedrius over 12 years
      It works for me, so we're missing something that is not mentioned in question - custom binders, custom javascript form submit, something like that...
    • Darin Dimitrov
      Darin Dimitrov over 12 years
      How does the model class containing the Id property look like?
    • Darbio
      Darbio over 12 years
      I think you are right - the Id setter is protected. ASP MVC was swallowing the fact that it could not set the Id. Changing to a non protected setter solved the problem.
    • Manfred
      Manfred over 11 years
      @Macropus Thank you for the update that you added to your question. That gave me a clue where to look for in my case. It's a little unfortunate that by the looks of it programming by convention doesn't necessarily give you a lot of traces info, exception, etc. to tell you want you are doing wrong.
  • g9ncom
    g9ncom almost 11 years
    If you're looking at this post and you already have a public setter on your POCO, you may find this post useful: stackoverflow.com/questions/3606087/…