How do I get two different models on one page with partial views?

advertisements

I have a UserManager page where an admin is able to get all the accounts that have currently been registered, delete accounts, update accounts, and register new accounts all from the same page.

I have a controller which reutrns all the users in db.users in a list.

public ActionResult UserManager()
{
    if (User.IsInRole("1"))
    {
        var db = new ReviewLogsTestDBEntities();
        return View(db.Users.ToList());
    }
    else
    {
        return RedirectToAction("Index", "Home");
    }
}

That's working fine, and I have the delete working.
The problem comes when I want to get a registration form on the same page.

This what my view Looks like right now:

@model IEnumerable<ReviewLogs.User>

@{
    ViewBag.Title = "UserManager";
}

<h2>UserManager</h2>    

<div id="userDetails">
    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.UserName);
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Role)
            </th>

            <th></th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.UserName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Role)
                </td>

                <td>
                    @Html.ActionLink("Edit", "Edit", new { id = item.ID }) |
                    @Html.ActionLink("Delete", "Del", new { id = item.ID}, new { onclick = "return confirm('Are you sure you wish to delete this article?')"});
                </td>
            </tr>
        }

    </table>
    </div>

As you can see there is a model:

@model IEnumerable<ReviewLogs.User>

But I want my form to use its own RegisterModel which has required fields, regex statements, etc, that need to be filled. When the user presses submit they the UserManager page is reloaded and now shows the newly added user.

I thought I could create a partial view:

@model ReviewLogs.Models.RegisterModel

@{
    ViewBag.Title = "Register";
    ViewBag.SubHead = "Register";
}

@Html.ValidationSummary(true, "Creation of new Account has failed please check your fields.")
<p id="success">@ViewBag.SuccessMessage</p>
<br />
@using (Html.BeginForm())
{
    //The Registration Page the user sees

    //The userName label and textbox
    <div class="inputFields">
        @Html.LabelFor(model => model.userName)
        @Html.TextBoxFor(model => model.userName)
        @Html.ValidationMessageFor(model => model.userName)
    </div>

    //The accountType label and radioButton
    <div class="radioButtonAccountType">
        @Html.LabelFor(model => model.accountType)
        @Html.RadioButtonFor(model => model.accountType, "1")<span class="adminLabel">Admin</span>
        @Html.RadioButtonFor(model => model.accountType, "2")<span class="userLabel">User</span>
        @Html.ValidationMessageFor(model => model.accountType)
    </div>

    <input class="submitButton" type="submit" value="Create User" style="margin-left:140px;margin-bottom: 20px;" />

}

And In my UserManager View I added:

@Html.Partial("Register");

But then I got this error:

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ReviewLogs.User]', but this dictionary requires a model item of type 'ReviewLogs.Models.RegisterModel'.

How can I get pass this so I am able to POST my registration?


Look for the @Html.Partial method overload which accepts a model, and call it via something like:

@Html.Partial("Register", Model.RegisterModel)

In order for this to work, probably the best bet would be to create a new Model that you pass into the UserManager view. This UserManagerModel will have two properties: IEnumerable<ReviewLogs.User>, used by the UserManagerView itself, and RegisterModel which you'll pass into the Partial view.