1

In ASP.NET Core MVC, I'm trying to set the pre-selected value for a SelectList - something which I thought would be a simple task, but it's driving me bonkers!

My controller contains the following:

ViewData["Scores"] = GetScoresAsSelectList();

and

private SelectList GetScoresAsSelectList()
{
    var scores =
        Enumerable.Range(0, 6)
        .Select(score => new
        {
            Value = score.ToString(),
            Text = Helper.ConvertScoreToText(score) // gets some unique text back
        })
       .OrderBy(o => o.Value)
       .ToList();
    scores.Insert(0, new { Value = string.Empty, Text = "Please select a value" });
    return new SelectList(scores, "Value", "Text", scores.FirstOrDefault().Value);
}

My view contains:

@{ var FieldScoreId = Guid.NewGuid(); }
<div class="form-group col-md-3">
    <label asp-for="FieldScore" class="control-label"></label>
    <select asp-for="FieldScore" class="form-control" asp-items="ViewBag.Scores" id="@FieldScoreId"></select>
    <span asp-validation-for="FieldScore" class="text-danger"></span>
</div>

The output (rendered HTML) is:

<select class="form-control" id="1fce2ac1-e63c-4b85-b69a-14b7713eafaf" data-val="true" data-val-range="The field Field Score must be between 0 and 5." data-val-range-max="5" data-val-range-min="0" data-val-required="The Field Score field is required." name="FieldScore">
<option value="">Please select a value</option>
<option selected="selected" value="0">None (0)</option>   <!-- WHY (OH WHY!?) IS THIS SELECTED? -->
<option value="1">1-Score (1)</option>
<option value="2">2-Score (2)</option>
<option value="3">3-Score (3)</option>
<option value="4">4-Score (4)</option>
<option value="5">5-Score (5)</option>
</select>

I've tried replacing scores.FirstOrDefault().Value with "". If Enumerable.Range(0, 6) was replaced with Enumerable.Range(1, 6) (start the range at 1, not 0), Please select a value would be selected.

I cannot figure out what the problem is, and it's driving me insane! :)

Many thanks for your help

4
  • 5
    When used on a select that is bound to a model property, the selected item will have a Value equal to the value of that property. The selected value set on the SelectList will be ignored. Commented Sep 17, 2020 at 15:45
  • Thanks @JohnathanBarclay - it makes sense now you've said it :) Commented Sep 17, 2020 at 18:00
  • 1
    @danwag: what @Johnathan said is correct. And I would like to add: since you're passing a view model to the view already, you can define a list there to contain all the possible options, instead of use a ViewBag. You shouldn't add "Please select a value" to the option list though. Instead, you can define that option in the view: <select asp-for=""><option value>- select -</option></select> Commented Sep 17, 2020 at 18:06
  • 1
    Thanks @DavidLiang. Normally I would pass the select list in a view model, rather than in the ViewBag, but the pattern has already been established in code :). A great idea to add the <option> inside the <select> in the view, rather than adding it to the model. Commented Sep 17, 2020 at 18:18

1 Answer 1

1

Thank you to @JohnathanBarclay for leading me down the right path.

I changed my controller to the following:

private SelectList GetScoresAsSelectList()
{
    var scores =
        Enumerable.Range(0, 6)
        .Select(score => new
        {
            Value = score,  //changed from string to int
            Text = Helper.ConvertScoreToText(score) // gets some unique text back
        })
       .OrderBy(o => o.Value)
       .ToList();
    scores.Insert(0, new { Value = -1/* changed from "" to -1 */, Text = "Please select a value" });
    return new SelectList(scores, "Value", "Text", scores.FirstOrDefault().Value);
}

Also in the controller, in the Add GET method, I set FieldScore to -1. Works well: the dropdown defaults to "please select" and the dropdown has to be changed from "please select" as the model requires a range between 0 and 5.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.