MVC DropDownListFor not selecting value from model

2019-01-14 03:35发布

I have read through this question ASP.NET MVC DropDownListFor not selecting value from model and answer but I don't know the solution to my problem.

This is my view:

@foreach (var adjusterLanguages in Model.adjusterLanguages)
{
    <div class="editor-field row">
        @Html.DropDownListFor(model => Model.adjusterLanguages[i].languageID,
                              (SelectList)ViewBag.ForeignLanguages) 
        @Html.ValidationMessageFor(model =>Model.adjusterLanguages[i].languageID)
    </div>

    <div style="clear: left;"></div>

    i++;
}

I can confirm that the model data is being populated (from my controller):

model.adjusterLanguages = adjLangs;

So, how can I make it select the items when the model gets sent to the view?

The generated html is as follows:

<div class="editor-field row">
    <select id="adjusterLanguages_0__languageID" name="adjusterLanguages[0].languageID"><option value="">--Select--
        </option>
        <option value="94c5be88-814e-4719-9784-587eb88aa975">Afrikanns</option>
        <option value="37b7bf71-7f4e-47c2-8b81-652b0d63dbcb">Albanian</option>
        <option value="c94d6d85-0ba2-47d7-932e-2a61feba37b3">Arabic</option>
        <!-- ... truncated for brevity ... -->
    </select> 
    <span class="field-validation-valid" data-valmsg-for="adjusterLanguages[0].languageID" data-valmsg-replace="true"></span>
</div>
<div style="clear: left;"></div>
<div class="editor-field row">
     <select id="adjusterLanguages_1__languageID" name="adjusterLanguages[1].languageID">
          <option value="">--Select--</option>
          <option value="94c5be88-814e-4719-9784-587eb88aa975">Afrikanns</option>
          <option value="37b7bf71-7f4e-47c2-8b81-652b0d63dbcb">Albanian</option>
          <option value="c94d6d85-0ba2-47d7-932e-2a61feba37b3">Arabic</option>
          <!-- ... truncated for brevity ... -->
     </select> 
     <span class="field-validation-valid" data-valmsg-for="adjusterLanguages[1].languageID" data-valmsg-replace="true"></span>
</div>

6条回答
Melony?
2楼-- · 2019-01-14 03:55

In my opinion one item of the ViewBag.ForeignLanguages should have Selected property set to true. DropDownListFor method select item based on ModelState. Here you have source code of DropDownListFor method an there is something like:

object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));

And if that value is null then selected value is retrieved from Selected property

查看更多
萌系小妹纸
3楼-- · 2019-01-14 04:03

I added an extension method to enforce the value selection. It also preserves view state data on a page reload.

public static class SelectListExtensions
{
    public static SelectList SelectValue(this SelectList selectList, object value)
    {
        return new SelectList(selectList, "Value", "Text", value);
    }
}

Usage is:

selectList = selectList.SelectValue(someValue);
查看更多
Lonely孤独者°
4楼-- · 2019-01-14 04:07

When you're populating ViewBag.ForeignLanguages in the controller, on the item that should be selected, set the .Selected property to true.

However, you'll have an issue with this because you have many items using the same ForeignLangauges list of items.

You'll need to create one list for each adjusterLanguages in your list. They cannot share the same list because adjusterLanguages[0] needs a different item selected than adjusterLanaguages[1]

Edit:

I like this model:

public class AdjusterLanguageModel
{
  public Guid LanguageId { get; set; }
  List<SelectListItem> ForeignLanguages{ get; set; }
}

public class AdjusterListModel
{
  public List<AdjusterLanguageModel> AdjusterLanguages { get; set }
}

In the controller, you populate your list with an ID and it's own list of available languages.

In your view:

@foreach (var adjusterLanguages in Model.AdjusterLanguages)
{
    <div class="editor-field row">
        @Html.DropDownListFor(model => adjusterLanguages[i].LanguageID,
          adjusterLanguages[i].ForeignLanguages) 
        @Html.ValidationMessageFor(model => adjusterLanguages[i].LanguageID)
    </div>

    <div style="clear: left;"></div>

    i++;
}

So each DropDownListFor get's it's own list of languages.

查看更多
等我变得足够好
5楼-- · 2019-01-14 04:09

I found the answer! Thanks to all for your help. When I change my code to the following, it works. The code simply specifies the selected value:

@Html.DropDownListFor(
   model => Model.adjusterLanguages[i].languageID, 
   new SelectList(
       ViewBag.ForeignLanguages, "Value", "Text", 
       @Model.adjusterLanguages[i].languageID)) 
查看更多
我只想做你的唯一
6楼-- · 2019-01-14 04:11

I'm sending IEnumerable in SList instead of ViewBag

@Html.DropDownListFor(model => Model.list[i].Id, new SelectList(Model.SList, "Value", "Text", Model.list[i].Id), htmlAttributes: new { @class = "form-control" })
查看更多
Explosion°爆炸
7楼-- · 2019-01-14 04:22

I know this is an old question, but just in case someone is facing the same problem than me. In my case was that I accidentally was using a normal variable instead of a property in the model, as soon as I set it as a property instead it started working.

查看更多
登录 后发表回答