MVC post not adding values to model

.net, asp.net-mvc, asp.net-mvc-4, c#, razor

Solution

The `DefaultModelBinder` only able to bind public properties.

Change your property setter to public and it should work fine:

[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }

If you can't do that you will need create a custom model binder which deals with private setters.

However as a better approach instead of using your `UserProfile` directly. Create a `UserProfileViewModel` where your `UserId` is public and use that in your View and Controller action. In this case you need to map between your `UserProfile` and the `UserProfileViewModel` but there are good tools exists for that task like AutoMapper.

Problem

I have a simple edit form for a user model but when I post back, none of the hidden input values are being applied to model and I'm not sure why this is happening. My Razor: ``` @model CMS.Core.Models.UserProfile @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset class="normalForm"> <legend>User Profile</legend> @Html.HiddenFor(model => model.UserId) <div class="formRow"> <div class="editor-label"> @Html.LabelFor(model => model.EmailAddress) </div> <div class="editor-field"> @Html.TextBoxFor(model => model.EmailAddress, new { @class = "textbox" }) @Html.ValidationMessageFor(model => model.EmailAddress) </div> </div> <div class="formRow"> <div class="editor-label"> @Html.LabelFor(model => model.FirstName) </div> <div class="editor-field"> @Html.TextBoxFor(model => model.FirstName, new { @class = "textbox" }) @Html.ValidationMessageFor(model => model.FirstName) </div> </div> <div class="buttonRow"><input type="submit" value="Save" class="button" /></div> </fieldset> } ``` My Controller: ``` [HttpPost] public ActionResult Edit(UserProfile user) { if (ModelState.IsValid) { user.Save(); return RedirectToAction("Index"); } return View(user); } ``` UserProfile class: ``` [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; private set; } [Required(ErrorMessage = "Please enter an email address")] [StringLength(350)] [DataType(DataType.EmailAddress)] [Display(Name = "Email Address")] public string EmailAddress { get; set; } [StringLength(100)] [DataType(DataType.Text)] [Display(Name = "First Name")] public string FirstName { get; set; } } ``` If I try `user.UserId` it returns zero (as it is an int) but if I try `Request["UserId"]` it returns the correct value so the value is being posted correctly - just not added into the `UserProfile` model. Does anyone know why this is happening or what I can do to solve it Thanks

Original source