如何在 ASP.NET MVC 3 中为填充的下拉列表创建视图模型

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 3 中为填充的下拉列表创建视图模型【英文标题】:How do I create a view model for a populated drop down list in ASP.NET MVC 3 【发布时间】:2012-04-10 13:56:18 【问题描述】:

我正在尝试自学 MVC3。我正在从网络表单转换。

我需要创建一个包含下拉列表的视图模型,我可以将其传递给控制器​​并最终在视图中呈现。

我怎样才能做到这一点?我有骨架,但我不知道实际为视图创建名称值对的代码是什么。

namespace DH.ViewModels

    public class SharedLayoutViewModel
    
        public IEnumerable<SelectListItem> Products
        
            //some code to setup the value/name pairs to be rendered in the view.
            //example: 
            //<option value="1">Mustard</option>
            //<option value="2">Ketchup</option>
            //<option value="3">Mayo</option>
            //<option value="4">Relish</option>
            //<option value="5">BBQ</option>
         
     
  

谢谢

【问题讨论】:

【参考方案1】:

我会在我的主视图模型中为产品创建一个类并创建产品属性,它是列表类型

public class ProductViewModel

  public int ID  set;get;
  public string Name  set;get;


public class OrderViewModel

  public int OrderNumber  set;get;
  public List<ProductViewModel> Products  set;get;
  public int SelectedProductId  set;get;    

在你的控制器动作方法中

public ActionResult Order()
     
   var orderVM=new OrderViewModel();
   //Items hard coded for demo. You may replace with values from your db
   orderVM.Products= new List<ProductViewModel>
    
        new ProductViewModel ID=1, Name="IPhone" ,
        new ProductViewModel ID=2, Name="MacBook Pro" ,
        new ProductViewModel ID=3, Name="iPod"            
    ;
   return View(orderVM);

在您的视图中,它是 OrderViewModel 的强类型。

@model ORderViewModel
@using (html.BeginForm())

  <p> 
    @Html.DropDownListFor(x => x.SelectedProductId ,
                     new SelectList(Model.Products, "ID", "Name"), "-- Select Product--")
  </p>
  <input type="submit" />

我还添加了一个SelectedProductId 属性,因此当用户将表单发回控制器时,您将从该属性的下拉列表中获取用户选择的值。

您还可以使用通用SelectListItem 类型集合作为您的视图模型属性来传输下拉数据,而不是您的自定义ProductViewModel 集合。

public class OrderViewModel

  public int OrderNumber  set;get;
  public List<SelectListItem> Products  set;get;
  public int SelectedProductId  set;get;    

在 GET 操作中,

public ActionResult Order()
     
   var orderVM=new OrderViewModel();
   //Items hard coded for demo. You may replace with values from your db
   orderVM.Products= new List<SelectListItem>
    
        new SelectListItem Value = "1", Text = "IPhone",
        new SelectListItem Value = "2", Text = "MacBook",
        new SelectListItem Value = "3", Text = "Candy"
    ;
   return View(orderVM);

在你看来,

@Html.DropDownListFor(x => x.SelectedProductId, Model.Products, "-- Select Product--")

编辑:根据 OP 的要求,编辑答案以使属性返回静态项目作为产品

我向 Products 属性添加了一个 get 实现以返回静态产品列表。

public class OrderViewModel

        private List<ProductViewModel> _products;
        public int OrderNumber  set; get; 
        public List<ProductViewModel> Products
        
            get
            
                if (_products == null)
                
                    _products = new List<ProductViewModel>();
                    _products.Add(new ProductViewModel  ID = 1, Name = "Ketchup" );
                    _products.Add(new ProductViewModel  ID = 1, Name = "Mustard" );
                    _products.Add(new ProductViewModel  ID = 1, Name = "Relish" );
                    _products.Add(new ProductViewModel  ID = 1, Name = "Mayo" );
                
                return _products;
            
        
       public int SelectedProductId  set;get;

现在在您的控制器中,您不需要调用 GetAvailableProducts 方法,因为它已经存在。所以控制器看起来像这样。

    public ActionResult Order()
    
        OrderViewModel orderVM = new OrderViewModel();           
        return View(orderVM);
    

这是输出。

如果您的产品中有很多项目,请将其移至一个方法并在他获得实现时调用该方法,而不是在那里编写。这是更清洁的方法。

【讨论】:

感谢您的回复。产品列表是静态的。我将在哪里创造这些价值?我是在控制器中设置值列表还是在视图模型中创建静态列表? @Maddhacker24 :您可以在 ViewModel 中创建它。 如果我有以下产品,你能告诉我填充这个选择列表的语法吗?番茄酱、芥末、调味酱、蛋黄酱、烧烤 完美。非常感谢您的帮助! @Shyju:我创建了一个 testingApplication 只是为了尝试一下,但是它不能正常工作。视图上有错误:“testingApplication1.ViewModel.ProductViewModel”不包含名为“Value”的属性。我可以知道它有什么问题吗?【参考方案2】:

我更喜欢这样做。

@Html.DropDownListFor(m => m.ProductId, new SelectList(Model.Products, "ID", "Name"))

所以我的视图模型只包含一个产品列表并在视图上生成选择列表。

【讨论】:

【参考方案3】:

为什么不能只在 ViewModel 中使用 SelectList? 它是一种包含选定值和项目列表本身的抽象。 您可以实现显示/编辑器模板并定义属性 DataTypeAttribute/UIHintAttribute 将特定模板与选择列表相关联。

public class ProductViewModel

    public int ID  set;get;
    public string Name  set;get;
    public SelectList Items get;set;

【讨论】:

SelectList 是特定于视图的构造。您可能希望将来将视图更改为不是下拉列表 - 所以您应该让 Items 的类型为 ItemViewModel(带有 Id 和名称,而不是值和标签),直到它在下拉列表中使用,此时您创建一个 SelectListItem从中。否则,当您想要进行此更改时,您需要更改您的视图模型(以及因此可能使用它的任何其他视图),而您应该只更改一个视图。查找“关注点分离”

以上是关于如何在 ASP.NET MVC 3 中为填充的下拉列表创建视图模型的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 ajax 使用数据库数据填充 ASP.NET MVC 4 下拉列表

如何从现有 SQL DB ASP.Net MVC 4 在下拉列表中填充数据

使用 Json 和 Jquery 的 Asp.net MVC4 中的级联下拉列表不填充

根据上一个列表中选择的值填充下拉列表(asp.net mvc3)

如何通过在 ASP.NET MVC 框架中调用 ajax 来显示 kendoDropDownList?

ASP.NET MVC 视图需要将选定的下拉列表和日历日期传递给模型