【问题标题】:What's best way to handle DropDownListFor in Asp.Net MVC 3?在 Asp.Net MVC 3 中处理 DropDownListFor 的最佳方法是什么?
【发布时间】:2011-07-22 20:11:42
【问题描述】:

我有这个控制器:

public ActionResult Novo()
{
   var products = context.Product.Select(x => new SelectListItem
   {
      Text = x.Name,
      Value = SqlFunctions.StringConvert((double)x.Id).Trim()
   }).ToList();

   MyViewModel myViewModel= new MyViewModel()
   {
      Products = products
   };

   return View(myViewModel);
}

[HttpPost]
public ActionResult Novo(MyViewModel myViewModel)
   {
      if (ModelState.IsValid)
      {
         ...

         context.SaveChanges();

         return RedirectToAction("Index");
      } else {
         var products = context.Product.Select(x => new SelectListItem
         {
            Text = x.Name,
            Value = SqlFunctions.StringConvert((double)x.Id).Trim()
         }).ToList();

         MyViewModel myViewModel= new MyViewModel()
         {
            Products = products
         };

         return View(myViewModel);
      }
}

我必须用这两种方法在 ViewModel 中填充 Products。

我的视图模型:

public class MyViewModel
{
   public IEnumerable<SelectListItem> Products { get; set; }
   public string ProductIdSelected { get; set; }
}

我的 HTML:

<div class="editor-field">
   @Html.DropDownListFor(model => model.ProductIdSelected, Model.Products)
</div>

问题出在我的控制器上,我必须用这两种方法填充 ViewModel。我不喜欢这样,我也不喜欢创建一个填充 ViewModel 的方法,因为当验证失败时,其他字段会继续填充,为什么我的 Products 字段也不会继续填充?我认为使用一种方法是丑陋的。有没有办法避免使用其他方法?

有没有办法在我的 ViewModel 中只填充一次产品,并在有人发布帖子但帖子无效时缓存产品列表。

如果没有,更好的方法是使用另一种方法。谢谢。

【问题讨论】:

  • “我也不喜欢创建填充 ViewModel 的方法。”所以你的意思是你不喜欢可重用的代码?
  • @Acaz - 如果您不想使用某种方法(我认为这是正确的选择),您将不得不将数据存储在某处。您可以缓存它(不保证在回发时存在),您可以以某种方式对其进行序列化并使用模型绑定器从值提供者重新加载。但是,我认为这是对问题的过度分析。只需使用一种方法...它是 C# 不可或缺的 :)!
  • 我不确定我是否在关注。当验证失败时,您期望会发生什么? “当验证失败时,其他字段继续填充,我认为这太丑陋了。”是什么意思。
  • @Dismissile - 我认为他是说 other 属性已加载(因为它们的值是通过值提供程序找到的),但未加载下拉列表,因为仅返回选定的 ID(标准表单发布...)。
  • 看看stackoverflow.com/questions/6568808/…它讨论了同样的问题

标签: .net asp.net-mvc razor


【解决方案1】:

创建一个单独的方法来填充您的 VM 有什么问题(对于 GET 和验证失败时的 POST)?

[HttpGet]
public ActionResult Novo()
{
    MyViewModel myViewModel= new MyViewModel();
    this.LoadProducts(myViewModel);
    return View(myViewModel);
}

[HttpPost]
public ActionResult Novo(MyViewModel myViewModel)
{
    if (ModelState.IsValid)
    {
         ...

         context.SaveChanges();

         return RedirectToAction("Index");
    }
    else 
    {
         MyViewModel myViewModel= new MyViewModel();
         this.LoadProducts(myViewModel);
         return View(myViewModel);
    }
}

private void LoadProducts(MyViewModel model)
{
    model.Products = context.Product.Select(x => new SelectListItem
    {
        Text = x.Name,
        Value = SqlFunctions.StringConvert((double)x.Id).Trim()
    }).ToList();
}

另外,您可以为LoadProducts 提供另一个参数,以便它可以设置所选项目。

【讨论】:

    猜你喜欢
    • 2012-09-18
    • 2012-04-08
    • 1970-01-01
    • 2012-09-07
    • 2011-03-19
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 2011-01-13
    相关资源
    最近更新 更多