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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With