【问题标题】:How do I create a view model for a populated drop down list in ASP.NET MVC 3如何在 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>
         }
     }
  }

谢谢

【问题讨论】:

    标签: c# asp.net asp.net-mvc-3


    【解决方案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从中。否则,当您想要进行此更改时,您需要更改您的视图模型(以及因此可能使用它的任何其他视图),而您应该只更改一个视图。查找“关注点分离”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 2011-10-11
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多