我最近一直在MVC工作,我很好奇初始化我的视图模型的最佳方法是什么。我应该直接在控制器中映射它,还是应该在视图模型的构造函数中初始化属性。此外,当有列表时,这是更好的做法,因为当出现验证错误时,您不必重新填充它们。
例如,如果我有以下型号:
public FooBarViewModel
{
public int FooBarId { get; set; }
public string SomeInitialProperty1 { get; set; }
public string SomeInitialProperty2 { get; set; }
public string SomeInitialProperty3 { get; set; }
public string SomeInitialProperty4 { get; set; }
public int FooId { get; set; }
public int BarId { get; set; }
public IEnumerable<Foo> Foos { get; set; }
public IEnumerable<Bar> Bars { get; set; }
}
然后是控制器:
public MyController : Controller
{
[HttpGet]
public ActionResult FooBar(int foobarId)
{
var foobar = _fooBarRepository.GetById(foobarId);
var model = new FooBarViewModel
{
FooBarId = foobar.Id;
SomeInitialProperty1 = foobar.SomeInitialProperty1;
SomeInitialProperty2 = foobar.SomeInitialProperty2;
SomeInitialProperty3 = foobar.SomeInitialProperty3;
SomeInitialProperty4 = foobar.SomeInitialProperty4;
Foos = foobar.Foos.ToList();
Bars = foobar.Bars.ToList();
}
return View(model);
}
[HttpPost]
public ActionResult FooBar(FooBarViewModel model)
{
if (ModelState.IsValid)
{
//process model
return RedirectToAction("Index");
}
var foobar = _fooBarRepository.GetById(model.FoobarId);
model.Foos = foobar.GetFoos.ToList();
model.Bars = foobar.GetBars.ToList();
return View(model);
}
}
或者我应该在我的模型中这样做:
public FooBarViewModel
{
public int FooBarId { get; set; }
public string SomeInitialProperty1 { get; set; }
public string SomeInitialProperty2 { get; set; }
public string SomeInitialProperty3 { get; set; }
public string SomeInitialProperty4 { get; set; }
public int FooId { get; set; }
public int BarId { get; set; }
public IEnumerable<Foo> Foos
{
get { return _foos; }
}
private IEnumerable<Foo> _foos;
public IEnumerable<Bar> Bars
{
get { return _bars; }
}
private IEnumerable<Bar> _bars;
public MyViewModel(FooBar foobar)
{
FooBarId = foobar.Id;
SomeInitialProperty1 = foobar.SomeInitialProperty1;
SomeInitialProperty2 = foobar.SomeInitialProperty2;
SomeInitialProperty3 = foobar.SomeInitialProperty3;
SomeInitialProperty4 = foobar.SomeInitialProperty4;
_foos = foobar.Foos.ToList();
_bars = foobar.Bars.ToList();
}
}
然后我的控制器:
public MyController : Controller
{
[HttpGet]
public ActionResult FooBar(int foobarId)
{
var foobar = _fooBarRepository.GetById(foobarId);
var model = new FooBarViewModel(foobar);
return View(model);
}
[HttpPost]
public ActionResult FooBar(FooBarViewModelmodel)
{
if (ModelState.IsValid)
{
//process model
return RedirectToAction("Index");
}
return View(model);
}
}
这是MVC中的首选约定,为什么它是最佳实践?另外,为什么选择一个而不是另一个呢?提前谢谢。
答案 0 :(得分:4)
一般来说,您需要重型和轻型控制器,因此您可以在控制器中尽可能少地工作。
一般设计模式的原因你应该在视图模型中初始化ViewModel?
答案 1 :(得分:4)
默认情况下,我不相信MVC会使用DependencyResolver在回发时创建视图模型的实例。因此,它只会创建一个带无参数构造函数的模型。这使得在构造函数中初始化对象变得不那么容易。
您可以创建一个通过DependencyResolver创建对象的自定义模型绑定器,但是您正在偏离正常练习。
我更喜欢使用AutoMapper初始化我的视图模型。
答案 2 :(得分:3)
我总是使用第二种方法,但使用“all-properties as parameters”-contructor而不是将“Foobar”插入构造函数(违反MVVM模式的种类,因为ViewModel应该保持独立)。 / p>
对我而言,这是最佳实践,因为您可以在视图模型中隐藏其他逻辑,并且您可以通过使用不同的构造函数来创建不同的行为。
答案 3 :(得分:3)
我认为你在第二种情况下做得很好。在我看来,准备好使用对象是该对象本身的责任。
如果您在其他地方需要该类的其他实例,该怎么办?您必须先从初始化代码的任何位置复制初始化代码。