【问题标题】:MVC DropDownList SelectedValue not displaying correctlyMVC DropDownList SelectedValue 未正确显示
【发布时间】:2012-04-06 04:05:46
【问题描述】:

我尝试搜索并没有找到任何解决我问题的方法。我在 Razor 视图上有一个 DropDownList,它不会显示我在 SelectList 中标记为 Selected 的项目。这是填充列表的控制器代码:

var statuses  = new SelectList(db.OrderStatuses, "ID", "Name", order.Status.ID.ToString());
ViewBag.Statuses = statuses;
return View(vm);

查看代码如下:

<div class="display-label">
   Order Status</div>
<div class="editor-field">
   @Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)
   @Html.ValidationMessageFor(model => model.StatusID)
</div>

我浏览了它,即使在视图中它也有正确的 SelectedValue 但是 DDL 总是显示列表中的第一项,而不管选择的值是什么。谁能指出我做错了什么让 DDL 默认为 SelectValue?

【问题讨论】:

  • 请参考以下链接。 stackoverflow.com/questions/5188563/…
  • alok_dida,我看了看,它看起来非常相似,除了在构造 SelectList 中选择的值使用整个对象而不是 ID.ToString() 就像我正在做的那样。但是我改变了我的代码来做同样的事情,它并没有解决问题。我缺少的两者之间有什么区别可以解决我的问题吗?
  • 我添加了一个详细的例子来说明如何做到这一点。
  • 这样可以解决dd stackoverflow.com/questions/11042660/…的问题 谢谢。

标签: asp.net-mvc asp.net-mvc-3 html.dropdownlistfor


【解决方案1】:

SelectList 构造函数的最后一个参数(您希望能够在其中传递选定的值 id)被忽略,因为 DropDownListFor 帮助器使用您作为第一个参数传递的 lambda 表达式并使用特定属性的值.

所以这是一个丑陋的方法:

型号:

public class MyModel
{
    public int StatusID { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        ViewBag.Statuses = statuses;

        var model = new MyModel();
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

查看:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)

这是使用真实视图模型的正确方法:

型号

public class MyModel
{
    public int StatusID { get; set; }
    public IEnumerable<SelectListItem> Statuses { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        var model = new MyModel();
        model.Statuses = statuses;
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

查看:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, Model.Statuses)

【讨论】:

  • 很好的答案,感谢您解释问题并举例说明如何解决问题。感谢您的帮助。
  • 我真的不明白 StatusID 绑定在哪里? SelectList的第四个值不是选中的值吗?您实际上并没有在任何地方告诉选择列表吗?它只是知道还是我要疯了?我无法让它工作以预先选择许多下拉列表:(
  • @ppumkin,不,当您使用视图模型和强类型帮助器时,您不需要 SelectList 构造函数的第四个参数。这就是x =&gt; x.StatusID 所做的。顺便说一句,从我的示例中可以看出,我什至没有使用 SelectList 构造函数,因为我的视图模型属性是 IEnumerable&lt;SelectListItem&gt; 并且可以直接绑定到 DropDownListFor。
  • 我从来不知道。再次感谢。我现在一切正常了 :) 很高兴 :)
  • 预填充模型解决了我的问题,不过谷歌搜索了一个多小时!
【解决方案2】:

为每个视图创建一个视图模型。这样做你只会在屏幕上包含需要的内容。由于我不知道您在哪里使用此代码,我们假设您有一个 Create 视图来添加新订单。

为您的 Create 视图创建一个新的视图模型:

public class OrderCreateViewModel
{
     // Include other properties if needed, these are just for demo purposes

     // This is the unique identifier of your order status,
     // i.e. foreign key in your order table
     public int OrderStatusId { get; set; }
     // This is a list of all your order statuses populated from your order status table
     public IEnumerable<OrderStatus> OrderStatuses { get; set; }
}

订单状态类:

public class OrderStatus
{
     public int Id { get; set; }
     public string Name { get; set; }
}

在您的创建视图中,您将拥有以下内容:

@model MyProject.ViewModels.OrderCreateViewModel

@using (Html.BeginForm())
{
     <table>
          <tr>
               <td><b>Order Status:</b></td>
               <td>
                    @Html.DropDownListFor(x => x.OrderStatusId,
                         new SelectList(Model.OrderStatuses, "Id", "Name", Model.OrderStatusId),
                         "-- Select --"
                    )
                    @Html.ValidationMessageFor(x => x.OrderStatusId)
               </td>
          </tr>
     </table>

     <!-- Add other HTML controls if required and your submit button -->
}

您的 Create 操作方法:

public ActionResult Create()
{
     OrderCreateViewModel viewModel = new OrderCreateViewModel
     {
          // Here you do database call to populate your dropdown
          OrderStatuses = orderStatusService.GetAllOrderStatuses()
     };

     return View(viewModel);
}

[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
     // Check that viewModel is not null

     if (!ModelState.IsValid)
     {
          viewModel.OrderStatuses = orderStatusService.GetAllOrderStatuses();

          return View(viewModel);
     }

     // Mapping

     // Insert order into database

     // Return the view where you need to be
}

这将在您单击提交按钮时保留您的选择,并被重定向回创建视图以进行错误处理。

我希望这会有所帮助。

【讨论】:

    【解决方案3】:

    当你在模型中声明它时,确保你的返回选择值是一个字符串而不是整数。

    例子:

    public class MyModel
    {
        public string StatusID { get; set; }
    }
    

    【讨论】:

    • 这个对我有用,但我将属性重构为一个字符串。
    • 有没有办法在选择值中设置整数值。
    【解决方案4】:

    对我来说,这个问题是由大的 css 填充数字(下拉字段内的顶部和底部填充)引起的。基本上,该项目正在显示但不可见,因为它已经下降了。我通过减小填充数字来修复它。

    【讨论】:

      【解决方案5】:

      我留下这个以防它帮助别人。我有一个非常相似的问题,没有一个答案有帮助。

      我的 ViewData 中有一个与 lambda 表达式的选择器同名的属性,基本上就像您将 ViewData["StatusId"] 设置为一样。

      在 ViewData 中更改匿名属性的名称后,DropDownList 助手按预期工作。

      虽然很奇怪。

      【讨论】:

        【解决方案6】:

        我的解决方案是这样... 当前选定的项目是 ProjectManagerID。

        查看:

        @Html.DropDownList("ProjectManagerID", Model.DropDownListProjectManager, new { @class = "form-control" })
        

        型号:

        public class ClsDropDownCollection
        {
           public List<SelectListItem> DropDownListProjectManager { get; set; }
           public Guid ProjectManagerID { get; set; }
        }
        

        生成下拉菜单:

        public List<SelectListItem> ProjectManagerDropdown()
        {
            List<SelectListItem> dropDown = new List<SelectListItem>();
            SelectListItem listItem = new SelectListItem();
        
            List<ClsProjectManager> tempList = bc.GetAllProductManagers();           
        
            foreach (ClsProjectManager item in tempList)
            {
                listItem = new SelectListItem();
                listItem.Text = item.ProjectManagerName;
                listItem.Value = item.ProjectManagerID.ToString();
                dropDown.Add(listItem);
            }
            return dropDown;
        }
        

        【讨论】:

          【解决方案7】:

          请在下面找到示例代码。

          public class Temp
              {
                  public int id { get; set; }
                  public string valueString { get; set; }
              }
          

          控制器

          public ActionResult Index()
                  {
                      // Assuming here that you have written a method which will return the list of Temp objects.
                      List<Temp> temps = GetList();
          
                      var tempData = new SelectList(temps, "id", "valueString",3);
                      ViewBag.Statuses = tempData;
          
                      return View();
                  }
          

          查看

           @Html.DropDownListFor(model => model.id, (SelectList)ViewBag.Statuses)
              @Html.ValidationMessageFor(model => model.id)
          

          【讨论】:

          • 我希望您只是从一些示例代码中复制并粘贴了这段代码。这可以很容易地在 for 循环中完成。很抱歉成为代码纳粹,但老实说,即使不使用生产代码,我们也应该停止传播不良代码。除非您是完全不同级别的编程入门。
          • 各位,这只是一个例子。无论如何,用户都可以创建一个列表。我创建列表的方式对他来说没有任何意义,因为他将拥有自己的收藏。对他来说重要的是 C# 的最后 2 行代码和 HTML 的 2 行代码。请不要在没有逻辑的情况下对代码投反对票。您也可以编辑帖子。如果答案不正确,您可以对答案投反对票。这段代码有什么问题?
          • @ppumkin - 如果你的眼睛在燃烧,那么编辑代码。代码有什么问题?
          • @pqsk - 我没有从示例代码中复制它。我刚开始在这里写代码并复制粘贴。如果您认为这是一个糟糕的代码,请对其进行编辑或给我留言,但您为什么要投反对票?没有理由投反对票。
          猜你喜欢
          • 2015-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多