简体   繁体   中英

How to get two different models on one page with Partial Views?

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.

Just new up a copy of register model in your view and pass it to the partial:

@Html.Partial("Register", new Namespace.To.RegisterModel())

Just make sure to make the form for registering post to a separate action. You should not try to have this one action handle multiple different types of posts. You can pass a return URL (basically just Request.RawUrl ) in a hidden field in your form, and then if this value is present, you can use it to redirect back to the same page. For example:

@Html.Hidden("returnUrl", Request.RawUrl)

Then,

[HttpPost]
public ActionResult Register(RegisterModel model, string returnUrl)
{
    // do the register thing

    if (!String.IsNullOrWhiteSpace(returnUrl))
    {
        return Redirect(returnUrl);
    }

    return RedirectToAction("Index"); // or whatever should be default
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM