Razor Select元素无法显示ViewModel值,如何正确填充?
问题描述
传递包含列表的ViewModel到页面,尝试用ViewModel列表的值填充表单,其他控件均可正常显示对应值,但Select元素始终默认显示ViewBag.rateList的内容,请问如何正确填充该Select元素?
视图代码
@for (var i = 0; i < 6; i++) { var rateRequest = Model.RateRequests[i]; <div class="rate-request-row"> <!-- Input fields for rate request properties --> <!-- Use Model.RateRequests[i].Property to bind to the RateRequest properties --> <div class="col-md-12" style="display:inline-flex;"> <input class="form-control col-md-2" type="date" name="RateRequests[@i].ServiceDate" value="@rateRequest.ServiceDate.ToString("yyyy-MM-dd")" /> <input class="form-control col-md-2" type="time" name="RateRequests[@i].ServiceTime" value="@rateRequest.ServiceTime.ToString("hh\:mm")" /> <select class="form-control col-md-3" name="RateRequests[@i].RateCode"> <option value="@rateRequest.RateCode[i]"></option> @foreach (var item in ViewBag.rateList) { <option value="@item.Value">@item.Text</option> } </select> <input class="form-control col-md-1" type="number" name="RateRequests[@i].Quantity" placeholder="Quantity" value="@rateRequest.Quantity" /> <input class="form-control col-md-1" type="number" name="RateRequests[@i].Modifier" step=".01" placeholder="Modifier" value="@rateRequest.Modifier" /> </div> </div> }
控制器代码(供参考)
[HttpPost] public IActionResult TwoRateBuilder(RateQuoteVM rateQuoteVM, string zero) { ViewBag.zero = zero; // Populate the dropdown list for rate codes List<SelectListItem> rateList = new List<SelectListItem>(); var allRates = _context.ListRates.Select(rate => new { rate.RateCode, rate.RateName }).ToList(); rateList.Add(new SelectListItem() { Value = "", Text = "" }); foreach (var rate in allRates) { rateList.Add(new SelectListItem() { Value = rate.RateCode, Text = rate.RateName }); } ViewBag.rateList = rateList; // Remove rate requests with empty rate codes rateQuoteVM.RateRequests = rateQuoteVM.RateRequests .Where(rr => !string.IsNullOrWhiteSpace(rr.RateCode)) .ToList(); List<RateQuoteFactory.RateQuoteIndex> allQuotes = new List<RateQuoteFactory.RateQuoteIndex>(); foreach (var rateRequest in rateQuoteVM.RateRequests) { var quotes = _rateQuoteFactory.RateQuote(rateRequest.ServiceDate, rateRequest.ServiceTime, null, rateRequest.RateCode, rateRequest.Quantity, rateRequest.Modifier, null); allQuotes.AddRange(quotes); } rateQuoteVM.Quotes = allQuotes; // Ensure there are exactly 6 rate requests in the view model while (rateQuoteVM.RateRequests.Count < 6) { rateQuoteVM.RateRequests.Add(new RateRequest { ServiceDate = TimeZoneFactory.GetTimeEST().AddDays(1), ServiceTime = TimeSpan.Parse("8:00"), RateCode = "", Quantity = 1, Modifier = 1.0m }); } //return RedirectToAction("TwoRateBuilder", "Post", new { zero }); return View(rateQuoteVM); }
解决方案
问题根源
- 视图中手动添加的空option存在错误:
@rateRequest.RateCode[i]无效,因为rateRequest是单个RateRequest实例,RateCode是字符串属性而非数组,此处应直接用@rateRequest.RateCode。 - 循环生成的option未设置
selected属性,导致浏览器默认显示列表第一个选项,而非ViewModel中的对应值。
方案一:修复手动编写的Select选项
删除错误的空option,同时在循环中判断当前选项值是否匹配ViewModel的RateCode,匹配则添加selected属性:
<select class="form-control col-md-3" name="RateRequests[@i].RateCode"> @foreach (var item in ViewBag.rateList) { <option value="@item.Value" @(item.Value == rateRequest.RateCode ? "selected" : "")>@item.Text</option> } </select>
注:控制器中已为rateList添加空值选项,无需手动额外添加。
方案二:使用Html.DropDownListFor辅助方法(推荐)
ASP.NET MVC的辅助方法会自动绑定ViewModel的值并设置选中状态,代码更简洁且不易出错:
@Html.DropDownListFor(m => m.RateRequests[i].RateCode, (IEnumerable<SelectListItem>)ViewBag.rateList, new { @class = "form-control col-md-3" })
此方法会自动根据Model.RateRequests[i].RateCode的值,在ViewBag.rateList中找到匹配的选项并标记为选中。
内容的提问来源于stack exchange,提问作者Nick Fleetwood
相关产品推荐
相关产品推荐

