![](/img/trans.png)
[英]How to add multiple records in List along with other model in view-model Linq - ASP.NET-MVC5
[英]How to construct an instance of a view-model when using Asp.Net MVC 5 framework and IoC container?
我正在使用ASP.NET MVC 5框架以及Unity-Container编写一个项目来处理我的依赖项。
我正在寻找在Asp.Net MVC 5应用程序中使用IoC
容器时处理构造视图模型的最佳实践。 我希望这个问题不被认为是基于观点的,并且可以解决。
我有以下视图模型类
public class CategoryReportViewModel
{
public IUnitOfWork UnitOfWork { get; set; }
public IEnumerable<object> Records { get; set; }
// ....
public TasksSummaryByProductViewModel(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
public void SetFilters()
{
// Do something.....
UnitOfWork.....
}
public void SetData()
{
// Do something.....
Records = UnitOfWork.....
}
}
如您所见,我的CategoryReportViewModel
类需要IUnitOfWork
的实例,以允许我的方法执行其任务“除非我手动将IUnitOfWork
传递给需要它的每个方法”。 我想知道什么是建立CategoryReportViewModel
实例的正确方法。 是通过IoC
容器还是通过旧方法通过构造函数传递IUnitOfWork
实例?
换句话说,使用我的视图模型的正确方法是什么?
遵循这些是尝试应对这种情况时想到的方法,但是哪种方法正确? 也许还有其他选择?
一,老旧手工更新策略
public class ReportsController : Controller
{
protected IUnitOfWork UnitOfWork { get; set; }
public ReportsController(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
[HttpGet]
public ActionResult CategoryByName()
{
var viewModel = new CategoryReportViewModel(UnitOfWork);
viewModel.SetFilters();
return View(viewModel);
}
[HttpPost, ValidateAntiForgeryToken]
public ActionResult CategoryByName(CategoryReportViewModel viewModel)
{
viewModel.UnitOfWork = UnitOfWork; // This is ugly
if (ModelState.IsValid)
{
viewModel.SetData();
}
viewModel.SetFilters();
return View(viewModel);
}
}
第二,手动更新,但将UnitOfWork
传递给需要它的任何方法
public class ReportsController : Controller
{
protected IUnitOfWork UnitOfWork { get; set; }
public ReportsController(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
[HttpGet]
public ActionResult CategoryByName()
{
var viewModel = new CategoryReportViewModel();
viewModel.SetFilters();
return View(viewModel);
}
[HttpPost, ValidateAntiForgeryToken]
public ActionResult CategoryByName(CategoryReportViewModel viewModel)
{
if (ModelState.IsValid)
{
viewModel.SetData(UnitOfWork);
}
viewModel.SetFilters(UnitOfWork);
return View(viewModel);
}
}
第三,在注册CategoryReportViewModel
之后使用IoC
容器。 但是这将需要我修改Asp.Net MVC 5的默认行为,因为我的视图模型可能/没有默认构造函数。
public class ReportsController : Controller
{
[HttpGet]
public ActionResult CategoryByName()
{
var viewModel = DependencyResolver.Current.GetService<CategoryReportViewModel>();
viewModel.SetFilters();
return View(viewModel);
}
// This will now work since I my view-model does not have a default constructor
// unless I override the `DefaultModelBinder` class somehow to resolve the class
// from the IoC container
[HttpPost, ValidateAntiForgeryToken]
public ActionResult CategoryByName(CategoryReportViewModel viewModel)
{
if (ModelState.IsValid)
{
viewModel.SetData();
}
viewModel.SetFilters();
return View(viewModel);
}
}
在这方面可以有不同的方法和意见,但我发现最有效的模式是使ViewModels是“哑” DTO,其属性由控制器创建并填充。 将服务注入控制器,并在您的操作方法中包含所有业务逻辑。
换句话说, SetFilters()
和SetData()
可能应该在控制器上,并将模型作为参数。
public class ReportsController : Controller
{
protected IUnitOfWork UnitOfWork { get; set; }
public ReportsController(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
[HttpGet]
public ActionResult CategoryByName()
{
var viewModel = new CategoryReportViewModel();
this.SetFilters(viewModel);
return View(viewModel);
}
[HttpPost, ValidateAntiForgeryToken]
public ActionResult CategoryByName(CategoryReportViewModel viewModel)
{
if (ModelState.IsValid)
{
this.SetData(viewModel);
}
this.SetFilters(viewModel);
return View(viewModel);
}
private void SetFilters(CategoryReportViewModel viewModel)
{
// Do something.....
UnitOfWork.....
}
private void SetData(CategoryReportViewModel viewModel)
{
// Do something.....
Records = UnitOfWork.....
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.