DropDownList not populating with correct value in

2019-04-08 23:39发布

问题:

Okay, so I am having an issue getting a drop down list to choose the right value when it renders. It always defaults to index zero. However, I do have a view in another place where it renders just fine and selects the right value. I don't understand the difference.

Here is a trimmed down version of the view that works correctly:

@model AppName.Models.Guest

@using (Html.BeginForm())
{
    Attending Ceremony?<br />
    @Html.DropDownListFor(x => x.ConfirmCeremony, new SelectList(new Dictionary<string, string>
    {
        {"No Answer", "No Answer"},
        {"Yes", "Yes"},
        {"No", "No"},
        {"Maybe", "Maybe"}
    }, "key", "value"))
    @Html.ValidationMessageFor(x => x.ConfirmCeremony)
    <br />
    Attending Reception?<br />
    @Html.DropDownListFor(x => x.ConfirmReception, new SelectList(new Dictionary<string, string>
    {
        {"No Answer", "No Answer"},
        {"Yes", "Yes"},
        {"No", "No"},
        {"Maybe", "Maybe"}
    }, "key", "value"))
    @Html.ValidationMessageFor(x => x.ConfirmReception)
}

This view's model is of custom type Guest and when it renders the Attending Ceremony and Attending Reception drop down lists it correctly selects the option that is stored in the model. So if I come back to edit this guest I can see whatever I selected the last time I edited it, as expected. This view is an admin-only view and has more options than the next view.

Here is a trimmed down version of the view that doesn't work:

@model AppName.Models.Invite @*Invite has navigation property .Guests which is a collection of custom type Guest*@

@using (Html.BeginForm("SaveRSVP", "Wedding"))
{
    @Html.HiddenFor(x => x.Id)
    <table cellpadding="15px" cellspacing="0">
        <tr>
            <th>
                Name
            </th>
            @if (Model.Guests.Any(x => x.InvitedToCeremony))
            {
                <th>
                    Attending Ceremony?
                </th>
            }
            <th>
                Attending Reception?
            </th>
        </tr>
        @Html.EditorFor(x => x.Guests)
    </table>
    <br />
    <input type="submit" value="Save Responses" />
}

Html.EditorFor(x => x.Guests) loads an editor template that contains the drop down lists for Attending Ceremony and Attending Reception. Here is the editor template:

@model AlexAndNikki.Models.Guest

<tr>
    <td>
        @Html.HiddenFor(x => x.GuestID)
        @Model.FullName()
    </td>
    @if (Model.Invite.Guests.Any(x => x.InvitedToCeremony))
    {
        <td>
            @if (Model.InvitedToCeremony)
            {
                <text>
                @Html.DropDownListFor(x => x.ConfirmCeremony, new SelectList(new Dictionary<string, string>
                        {
                            {"No Answer", "No Answer"},
                            {"Yes", "Yes"},
                            {"No", "No"},
                            {"Maybe", "Maybe"}
                        }, "key", "value"))
                @Html.ValidationMessageFor(x => x.ConfirmCeremony)
                </text>
            }
            else
            {
                <text>
                    No more invites.
                </text>
            }
        </td>
    }
    <td>
        @Html.DropDownListFor(x => x.ConfirmReception, new SelectList(new Dictionary<string, string>
            {
                {"No Answer", "No Answer"},
                {"Yes", "Yes"},
                {"No", "No"},
                {"Maybe", "Maybe"}
            }, "key", "value"))
        @Html.ValidationMessageFor(x => x.ConfirmReception)
    </td>
</tr>

This does render the drop down lists and if I select items and do a POST the values are sent correctly to the server. However, the drop down lists do not select the correct value. I have even displayed the value stored in the model for the editor in plain text above the drop down list to verify that the correct values are making it to the editor and they are. It is a problem with the drop down lists. I suspect it is something to do with the fact that this editor is repeated for every Guest attached to the Invite but I cannot pinpoint the issue.

NOTE: This same thing happens if I don't use an editor, and instead do something like this in the view:

@for (int i = 0; i < Model.Guests.Count; i++)
{
                        @Html.DropDownListFor(x => x.Guests.ToList()[i].ConfirmCeremony, new SelectList(new Dictionary<string, string>
                        {
                            {"No Answer", "No Answer"},
                            {"Yes", "Yes"},
                            {"No", "No"},
                            {"Maybe", "Maybe"}
                        }, "key", "value"))
}

The same problem exists here, the drop down list will not select the value in the box. It just stays at index 0.

Any help is appreciated.

回答1:

There is another overload to the selectlist constructor that takes the selected value as the fourth parameter.

Try:

    @Html.DropDownListFor(x => x.ConfirmReception, new SelectList(new Dictionary<string, string>
        {
            {"No Answer", "No Answer"},
            {"Yes", "Yes"},
            {"No", "No"},
            {"Maybe", "Maybe"}
        }, "key", "value", Model.ConfirmReception))

Edit: Oops try that, assuming ConfirmReception is a property of the Guest object.

Edit: I had a similar problem with it not binding the value to the ddl. I'll just post something similar to what i had done.

Editorpage:

@model Models.OptionViewModel

@using (Html.BeginForm())
{ 
    @Html.EditorFor(r => r.OptionID, new { SelectList = Model.Options })

    @Html.SubmitButton()
}

ViewModel

public class OptionViewModel
{
    [DisplayName("Option")]
    [Required]
    [DataType("DropDownList")]
    public int OptionID { get; set; }

    public SelectList Options { get; private set; }

    public OptionViewModel()
    {
        Options = new SelectList(new OptionRepository().GetAll(), "ID", "Name");
    }

    public OptionViewModel(IOption option)
    {
        this.OptionID = option.OptionID;
        Options = new SelectList(new OptionRepository().GetAll(), "ID", "Name", OptionID);
    }
}

EditorTemplate: DropDownList.cshtml

@model int

<div class="editor-label">
    @Html.LabelFor(m => m)
</div>
<div class="editor-field">
    @Html.DropDownListFor(m => m, ViewBag.SelectList as SelectList, "Select an item...")
    @Html.ValidationMessageFor(m => m)
</div>