Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC post not adding values to model

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

like image 999
Pete Avatar asked Jan 22 '13 13:01

Pete


1 Answers

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.

like image 110
nemesv Avatar answered Sep 20 '22 10:09

nemesv