Zwoniar
Zwoniar

Reputation: 43

Passing two models to Controller using Ajax BeginForm()

I have View like this:

@model MVCApp.Models.User

@{
    ViewBag.Title = "EditUser";
}

<h2>Edycja użytkownika</h2>

@using (Ajax.BeginForm("SaveUser", "My", new AjaxOptions { UpdateTargetId = "Result" }))
{
    <fieldset>
        <legend>Zmień dane użytkownika</legend>
        <div id="EditUserForm">
            <div>
                @Html.LabelFor(m => Model.Login)
                @Html.TextBoxFor(m => Model.Login)
            </div>
            <div>
                @Html.LabelFor(m => Model.Password)
                @Html.TextBoxFor(m => Model.Password)
            </div>
            <div>
                @Html.LabelFor(m => Model.Name)
                @Html.TextBoxFor(m => Model.Name)
            </div>
            <div>
                @Html.LabelFor(m => Model.Surname)
                @Html.TextBoxFor(m => Model.Surname)
            </div>
            <div>
                @Html.LabelFor(m => Model.UserRole.Role)
                @Html.TextBoxFor(m => Model.UserRole.Role)
            </div>
            <input type="submit" value="Zapisz zmiany" />
            @Html.HiddenFor(m => Model.UserRole)
            @Html.HiddenFor(m => Model.UserRoleID)
            @Html.HiddenFor(m => Model.UserID)
        </div>
    </fieldset>
    <div id="Result"></div>
    @Html.ValidationSummary(true)
}

and method in MyController like this:

    [HttpPost]
    public ActionResult SaveUser(User user, UserRole role)
    {
        //code here

    }

but object role is not passed, either user.UserRole.

My User model class:

namespace MVCApp.Models
{

    public partial class User
    {
        public User()
        {
            this.Factures = new HashSet<Facture>();
            this.Settings = new HashSet<Setting>();
            this.Companies = new HashSet<Company>();
        }

        public int UserID { get; set; }
        public Nullable<int> UserRoleID { get; set; }
        public string Login { get; set; }
        public string Password { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }

        public virtual ICollection<Facture> Factures { get; set; }
        public virtual ICollection<Setting> Settings { get; set; }
        public virtual UserRole UserRole { get; set; }
        public virtual ICollection<Company> Companies { get; set; }
    }
}

And Role model class:

namespace MVCApp.Models
{

    public partial class UserRole
    {
        public UserRole()
        {
            this.Users = new HashSet<User>();
        }

        public int UserRoleID { get; set; }
        public string Role { get; set; }
        public virtual ICollection<User> Users { get; set; }
    }
}

so, How can I pass models like this, which has other reference types inside?

Upvotes: 0

Views: 1321

Answers (2)

user3559349
user3559349

Reputation:

The following line in your view make no sense

@Html.HiddenFor(m => Model.UserRole)

UserRole is a complex object, and depending on whether you have overridden its .ToString() method, it will render <input ... value="MVCApp.Models.UserRole" /> so when this posts back the DefaultModelBinder is trying to do model.UserRole = "MVCApp.Models.UserRole" which of course fails and the property is therefore null

Remove it, and instead bind to the properties of UserRole that you want posted back - as you have done with @Html.TextBoxFor(m => Model.UserRole.Role). For example @Html.HiddenFor(m => Model.UserRole.UserRoleID) but you already seem to have bound this with @Html.HiddenFor(m => Model.UserRoleID) so it might not be necessay to repeat it.

Upvotes: 1

aleha_84
aleha_84

Reputation: 8539

you can create your own submitting mechanism. Just use $.ajax and pass in its data property all your values. A bit more js code, but a lot more flexibility.

Upvotes: 0

Related Questions