2011-05-04 82 views
1

我是新来的ASP MVC 3,我有以下问题。我有一个表单发出发送数据到服务器的请求。该表单包含销售人员的DropDownList,此列表从数据库填充。其主要作用是这样的:如何不失去在ASP MVC 3中填充DropDownList的集合?

public ActionResult Index() 
{ 
    var viewModel = new OrderSearchViewModel(); 
    viewModel.SalesPeople = GetSalesPeopleList(); // This queries the DB 
    return View(viewModel); 
} 

而视图模型看起来是这样的:

public class OrderSearchViewModel 
{ 
     public string Id { get; set; } 
     public DateTime? StartDate { get; set; } 
     public DateTime? EndDate { get; set; } 
     public string PostCode { get; set; } 
     public int SalesPersonId { get; set; } 
     public string SalesPersonRef { get; set; } 
     public int OrderType { get; set; } 
     public string SerialNo { get; set; } 
     public string CustomerPO { get; set; } 
     public List<SalesPerson> SalesPeople { get; set; } 
} 

因此索引视图时,我提交的销售人员列表设置为空的形式(在指数HttpPost方法),我想显示与仍然填充的列表相同的视图。尽管如此,要做到这一点,我将不得不再次查询数据库。避免这样做的最佳做法是什么?

编辑:

我的帖子指数moethod代码是这样的:

[HttpPost] 
public ActionResult Index(OrderSearchViewModel viewModel) 
{ 
    var result = QueryOrders(viewModel); 
    //code update the model with the results 
    return View(viewModel); 
} 
+0

为什么你认为再次查询数据库不好?另外 - 这里有一些很好的介绍.NET MVC - > http://www.mvcconf.com/videos – Dan 2011-05-04 12:16:00

回答

0

使用Ajax提交表单,只是使用JSON返回岗位操作的结果到客户端 - 这样的数据库没有两次击中该列表并且用户也获得更平滑的体验。

+0

看起来是个好主意。但是,我是ASP MVC 3的新手,所以如果你有一个链接到某个地方,我可以看到这是如何完成的,我会非常感激。 – groovejet 2011-05-04 11:07:41

+0

这是一个有一些良好实践的视频 - 作为一个自由思考的开发人员,您需要确定您的方案中哪些部分最好 - > http://channel9.msdn.com/Series/mvcConf/mvcConf-2 -Eric-Sowell-Evolving-Practices-in-Using-jQuery-and-Ajax-in-ASPNET-MVC-应用 – Dan 2011-05-04 12:17:29

0

POST索引方法应该从FormCollection中获取SalesPeople的所有值。 您可以随时使用Request.FormCollection来查询所有表单数据。另一种选择是给你某种缓存DB数据:)。 反正请附上你POST索引方法的代码

+0

好的,现在在帖子 – groovejet 2011-05-04 12:32:00

0

你不应该在你的OrderSearchViewModel SalesPeople集合,因为它违反单一责任原则。您应该覆盖SalesPersonId的EditorTemplate并创建单独的操作,该操作将负责填充下拉菜单。

这里是我的应用程序中的代码,您可以使用它作为示例。请注意,我的CategoryId属性具有Guid类型 - 您应该替换Guid?与int ?.

模板覆盖使用mvcextensions:

public class CreateAccidentCommandMetadata : ModelMetadataConfiguration<CreateAccidentCommand> 
{ 
    public CreateAccidentCommandMetadata() 
    { 
     Configure(x => x.TrackingNumber) 
      .Required(); 

     Configure(x => x.CategoryId) 
      .Required() 
      .DisplayName("Category") 
      .Template(MVC.Accident.Views.EditorTemplates.Category); 
    } 
} 

模板内容:

@model Guid? 
@{Html.RenderAction(MVC.Category.List(ViewData.ModelMetadata, Model));} 

Category.List行动:

public virtual ActionResult List(ModelMetadata modelMetadata, Guid? selected) 
    { 
     ViewData.Model = queryService.GetList(new GetCategoryListQueryContext()) 
      .Select(x => new SelectListItem 
          { 
           Text = x.Name, 
           Value = x.Id.ToString(), 
           Selected = selected.HasValue && x.Id == selected 
          }) 
      .ToList(); 

     //it is important to set up ModelMetadata after model 
     ViewData.ModelMetadata = modelMetadata; 

     return View(); 
    } 

和非常简单的看法:

@model IEnumerable<SelectListItem> 
@Html.DropDownList(ViewData.ModelMetadata.PropertyName, Model) 
+0

我不完全相信这违反了单一责任,不一定是坏事(不能一次遵循所有的设计原则),尽管在他的情况下这可能是矫枉过正的...... – Dan 2011-05-04 12:21:25

+0

但它简化了很多东西 - 检索OrderSearchViewModel可能不关心业务员的行动,你不必应付TempData的保存请求之间的销售人员。防止第二次数据库查询的责任我将其放在基础设施级别 - 比如NHibernate的二级缓存。 – xelibrion 2011-05-04 12:48:05