What is this line of code ViewBag.RoleId = new Sel

2019-03-03 15:49发布

问题:

I find in a code example downloaded the following line of code in an Action method of a controller. ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name") or probably its async version ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Id", "Name");

I am not able to fathom whats happening here. Also in the corresponding view, I nowhere see ViewBag.RoleId being used. Instead I find in the view @Html.DropDownList("RoleId","No Roles")

There appears to be some trivial connection between the two. Can someone throw some light at whet I am missing.

The following is the line of code in the action method.

public async Task<ActionResult> Create()
{
    //Get the list of Roles
    ViewBag.RoleId = new SelectList(await RoleManager.Roles.ToListAsync(), "Id", "Name");
    return View();
}

And the corresponding view is as follows.

@model AspnetIdentitySample.Models.RegisterViewModel
@{
    ViewBag.Title = "Create";
}

<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
</hgroup>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset class="form-horizontal">
        <legend>Create a new user.</legend>
        <div class="control-group">
            @Html.LabelFor(m => m.UserName, new { @class = "control-label" })
            <div class="controls">
                @Html.TextBoxFor(m => m.UserName)
            </div>
        </div>
        <div class="control-group">
            @Html.LabelFor(m => m.Password, new { @class = "control-label" })
            <div class="controls">
                @Html.PasswordFor(m => m.Password)
            </div>
        </div>
        <div class="control-group">
            @Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
            <div class="controls">
                @Html.PasswordFor(m => m.ConfirmPassword)
            </div>
        </div>

        <div class="control-group">
            @Html.LabelFor(m => m.HomeTown, new { @class = "control-label" })
            <div class="controls">
                @Html.TextBoxFor(m => m.HomeTown)
            </div>
        </div>
        <h4>Select Role for User</h4>
        <hr />
        @Html.DropDownList("RoleId","No Roles")
        <div class="form-actions no-color">
            <input type="submit" value="Create" class="btn" />
        </div>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

回答1:

This line

ViewBag.RoleId = new SelectList(RoleManager.Roles, "Id", "Name") 

is creating a SelectList used by the @Html.DropDownList() or @Html.DropDownListFor() helpers to render the options in a <select> tag. The options will have a valueattribute defined by the Id property of Role and a display text defined by the Name property.

The view is using

@Html.DropDownList("RoleId","No Roles")

which binds to ViewData property RoleId (the ViewBag property) and the second argument renders an option label (the first option will have no value, but display the text "No Roles"

This is not a good usage, and it is recommended you use strongly typed helpers to bind to your model properties.

ViewBag.RoleList = new SelectList(RoleManager.Roles, "Id", "Name")

@Html.DropDownListFor(m => m.RoleID, (SelectList)ViewBag.RoleList,"No Roles")

where RoleID is a property in the model that will be bound to the selected options value