【问题标题】:How do I specify default option with an ASP.Net Core @Html.DropDownListFor?如何使用 ASP.Net Core @Html.DropDownListFor 指定默认选项?
【发布时间】:2020-11-10 22:26:41
【问题描述】:

我有一个如下所示的 .cshtml 文件:

@Html.DropDownListFor(
    m => m.MyModel.YesNoQuestion,                    // IHtmlHelper<TModel> htmlHelper
    new SelectList(Enum.GetValues(typeof(YesNo))),   // Expression<Func<TModel,TResult>>,
    "No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
    new { @class = "custom-select", @id = "MyModel.YesNoQuestion" }  // object htmlAttributes
)

不幸的是,生成的下拉列表如下所示:

No
Yes
No

在 Chrome 开发者工具中呈现的 HTML 如下所示:

<select class="custom-select" id="MyModel_YesNoQuestion" name="MyModel.YesNoQuestion">
  <option value>No</option>
  <option>Yes</option>
  <option>No</option>
</select>

我想要完成的是:

<select class="custom-select" id="MyModel_YesNoQuestion" name="MyModel.YesNoQuestion">
  <option>Yes</option>
  <option selected>No</option>
</select>

问:如何在 ASP.Net Core DropdownListFor 中指定默认选项?

问:第三个参数“否”究竟是做什么的?参数 2(“new SelectList”)生成我的下拉列表,那么参数 3 应该用于什么?

【问题讨论】:

  • 关于您的代码的一些小说明:您是否有理由使用标签助手而不是更具可读性的 Razor 语法?
  • @Jordy Deweer - 我当然愿意接受这个建议 :) 你介意发布一个例子作为回应吗?

标签: c# asp.net-core razor


【解决方案1】:

问:如何在 ASP.Net Core 中指定默认选项 DropdownListFor?

Html.DropDownListFor 扩展方法是一种强类型扩展方法,使用 lambda 表达式为指定的属性生成元素。

要设置默认选择值,我们可以通过第一个参数来设置,.cshtml.cs 页面代码如下:

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        } 
        [BindProperty]
        public YesNo YesNo { get; set; }   //Enum type, used to set the dropdownlist options
        [BindProperty]
        public string YesNoSelected { get; set; } //used to get the Dropdownlist seleted value.
        public void OnGet()
        {
            YesNoSelected = ((int)YesNo.Yes).ToString();  //set the default selected value.
        }
    }
    public enum YesNo
    {
        No, Yes
    }

.cshtml页面中的代码:这里我们要使用ValueText属性绑定DropDownList,然后,我们可以根据选择的值来设置默认值价值观:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text"),   // Expression<Func<TModel,TResult>>,
            //"Select Options",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

此外,您还可以通过SelectList(IEnumerable, String, String, Object)方法设置默认值(使用最后一个参数设置选择的值),尝试使用以下代码:

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        } 
        [BindProperty]
        public YesNo YesNo { get; set; }   //Enum type, used to set the dropdownlist options
        [BindProperty]
        public string YesNoSelected { get; set; } //used to get the Dropdownlist seleted value.
        public void OnGet()
        { 
           // YesNoSelected = ((int)YesNo.Yes).ToString();  //set the default selected value.
        }
    }
    public enum YesNo
    {
        No, Yes
    }

.cshtml 页面中的代码:

    @page
    @model IndexModel 

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text", ((int)YesNo.Yes).ToString()),   // Expression<Func<TModel,TResult>>, //set default selected value.
            //"Select Options",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

输出如下:

问:第三个参数“否”究竟是做什么的?论据 2(“新 SelectList") 生成我的下拉列表,那么参数 3 应该是什么 用于?

第三个参数是可选的,它将是 DropDownList 的第一项。一般来说,我们可以使用添加描述或提示,如下所示:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text", ((int)YesNo.Yes).ToString()),   // Expression<Func<TModel,TResult>>,
            "Select Yes or No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

结果如下图:

如果您不想添加此选项,只需将其删除即可。

编辑:

使用JavaScript/JQuery方法设置DropDownList默认选中值:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text"),   // Expression<Func<TModel,TResult>>,
            //"Select Yes or No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model_YesNoQuestion" }  // object htmlAttributes
        )

    <input type="hidden" id="ddldefault" value="1" />

    @section Scripts{
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script type="text/javascript">
            $(function () { 
                var ddldefault = $("#ddldefault").val(); //default selected value.
                $("#Model_YesNoQuestion option").each(function (index, item) {
                    //You could also use the text() method to check whether the option is selected or not.
                    if ($(item).val() == ddldefault) {
                        $(item).attr("selected", "selected");
                    }
                    else {
                        $(item).removeAttr("selected");
                    }
                });
            });
        </script> 
    }

【讨论】:

  • 谢谢! 1)你完全回答了我关于“第三个参数”的问题——很好的解释! 2)使用“SelectList(IEnumerable,String,String,Object)”设置默认值听起来很有希望,3)不幸的是,我不能弄乱 .cs 文件中的视图模型。因为我继承的设计不会“[BindProperty]”到各个字段。不,相反,有多个 EF 对象,每个对象都有 10 或 100 个字段。我不能弄乱底层的 EF 类文件;我无法为我的 .cshtml.cs 视图模型复制 EF 代码。我坚持修改 .cshtml。
  • @FoggyDay,你也可以尝试使用JQuery/JavaScript脚本来设置DropDownList默认选择值,检查编辑代码。
  • 我最终调整了您的 SelectList() 语法 - 它就像一个魅力。谢谢!
【解决方案2】:

不要使用标签助手,而是使用 razor 语法。

您的 .cshtml 如下所示:

@model SettingsViewModel

<form method="post" asp-controller="Home" asp-action="Index">
    <label asp-for="YesNo">Yes or no?</label>
    <select asp-for="YesNo" asp-items="Html.GetEnumSelectList<YesNoOptions>()"></select>
</form>

你的 SettingsViewModel.cs 喜欢他的:

    public class SettingsViewModel
    {
        public YesNoOptions YesNo { get; set; } = YesNoOptions.No;
    }

YesNoOtpions 枚举是这样的:

    public enum YesNoOptions
    {
        No, Yes
    }

如您所见,您仍然需要在视图模型中设置默认值,正如@Mika Tähtinen 在第一个答案中提到的那样。

【讨论】:

  • 1) 感谢您阐明“剃刀语法”的含义。 “@Html”语法(“Html helpers”)基本上是遗留语法,对吗? 2) 我正在尝试在我继承的遗留代码上构建。如果我可以避免的话,我不想搞乱“模型”。因为它看起来像这样:[BindProperty] public ReallyBigEFModel1 Answers1 { get; set; }; [BindProperty] public ReallyBigEFModel2 Answers2 { get; set; }... 如果我可以在我的 .cshtml 标记中设置愚蠢的默认值,那就太好了...
  • @FoggyDay - 嗯,我认为没有其他方法。但是,您可以添加一些 JavaScript 来选择默认值而不更改模型类吗? ;-)
【解决方案3】:

第三个参数是给一个默认的空项目,所以它不是你想要的。要默认选择“否”,您需要在初始化模型时将模型中的 YesNoQuestion 设置为 No。

【讨论】:

  • 不幸的是,这不是一个选项。有几个原因。问:有没有什么好的方法可以直接在我的 .cshtml 标记中指定默认选项?并确保将值(默认或手动选择)正确写入底层模型对象?
猜你喜欢
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 2022-08-02
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 2014-07-11
相关资源
最近更新 更多