有时您需要将一些额外的数据传递给视图。例如,添加新闻页面中的新闻组应该从数据库中检索。
我知道在视图中创建Db-context的实例并不是一个很好的做法。相反,我们可以向视图模型添加一些属性并将这些数据传递给视图或使用View-Bag并对其进行类型转换,但在这些情况下,您可能需要在HttpGet和HttpPost中编写一些代码,当您需要时在Get和Post方法中返回相同的视图。
进行此类操作的最佳做法是什么?有没有另一种方式写一次?
答案 0 :(得分:1)
据我了解,您似乎可以处理您需要执行的操作,但不喜欢get和post操作之间的代码重复。为此,只需将公共代码分解为控制器上的受保护或私有方法,两个操作都可以调用。例如,假设您需要一个Foo
项目的选择列表:
public class MyViewModel
{
...
public IEnumerable<SelectListItem> FooOptions { get; set; }
}
然后:
public class MyController : Controller
{
...
private void PopulateFooOptions(MyViewModel model)
{
var foos = db.Foos.ToList();
model.FooOptions = foos.Select(f => new SelectListItem { Value = f.Id.ToString(), f.Name });
}
public ActionResult Create()
{
var model = new MyViewModel();
PopulateFooOptions(model);
return View(model);
}
[HttpPost]
public ActionResult Create(MyViewModel model)
{
if (ModelState.IsValid)
{
// do stuff
}
PopulateFooOptions(model);
return View(model);
}
}
答案 1 :(得分:0)
要仅编写一次组件并在不同视图中重复使用它,请将组件打包到自己的操作中,并使用自己的ViewModel和Partial View。
如果无法从外部调用此操作,则将其归为[ChildActionOnly]
。数据库访问应该在此子操作中发生,数据应使用ViewModel传递给View。
使用@Html.Action("{actionName}", "{controllerName}")
在需要时呈现此操作生成的HTML。
例如:
NewsController包含子操作:
[ChildActionOnly]
public PartialViewResult ShowNewsGroups(long userId) {
var data = // ... read from DB using userId parameter
var vm = new ShowNewsGroupsViewModel {
GroupInfos = data
};
return PartialView("_ShowNewsGroups", vm);
}
部分视图_ShowNewsGroups.cshtml呈现新闻组:
@model ShowNewsGroupsViewModel
@for(var i = 0; i < Model.GroupInfos.Count(); i++) {
@Html.DisplayFor(m => m.GroupInfos[i])
}
主视图调用子操作并传递所需参数:
@Html.Action("ShowNewsGroups", "News", new { userId = Model.UserId }))
答案 2 :(得分:0)
出于这个特定原因,我们使用ViewModel概念 它只是一个需要财产的模型
例如,假设您有一个名为test的模型现在要传递一些额外的属性,如isValid的boolean和datetime Created 所以你的观点=模型将是
public class YourViewMode
{
public test mainModel{get;set;}
public bool isValid {get;set;}
public datetime Created {get;set;}
}
现在只需将此模型初始化为您的视图,这就是viewmodel的工作原理