通过向导方法填充ViewModel

我找到了如何在ASP MVC中执行向导的很好的答案。
asp.net mvc中的多步注册流程问题(splitted viewmodels,single model)

我只有一个与此相关的问题。 将数据填充到视图模型中的最佳做法是什么?

让我们说在第2步中我需要向用户显示数据列表。 列表数据来自DB。 然后我会继续为视图模型创建构造函数,还是应该在控制器中填充它?

这就是我的代码现在的样子。

模型

[Serializable] public class Step1ViewModel : IStepViewModel { public bool MyProperty { get; set; } } [Serializable] public class Step2ViewModel : IStepViewModel { // This needs to be populated with data, I need to display it in a list public List MyList { get; set; } } [Serializable] public class Step3ViewModel : IStepViewModel { public bool MyProperty { get; set; } } [Serializable] public class PublishViewModel { public int CurrentStepIndex { get; set; } public IList Steps { get; set; } public void Initialize() { Steps = typeof(IStepViewModel) .Assembly .GetTypes() .Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t)) .Select(t => (IStepViewModel)Activator.CreateInstance(t)) .ToList(); } public class PublishViewModelBinder : DefaultModelBinder { protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { var stepTypeValue = bindingContext.ValueProvider.GetValue("StepType"); var stepType = Type.GetType((string)stepTypeValue.ConvertTo(typeof(string)), true); var step = Activator.CreateInstance(stepType); bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, stepType); return step; } } public interface IStepViewModel { } 

调节器

 public ActionResult Publish(int? id) { var publish = new PublishViewModel(); publish.Initialize(); return View(publish); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Publish([Deserialize] PublishViewModel publish, IStepViewModel step) { publish.Steps[publish.CurrentStepIndex] = step; if (ModelState.IsValid) { if (!string.IsNullOrEmpty(Request["next"])) { publish.CurrentStepIndex++; } else if (!string.IsNullOrEmpty(Request["prev"])) { publish.CurrentStepIndex--; } else { // TODO: we have finished: all the step partial // view models have passed validation => map them // back to the domain model and do some processing with // the results return Content("thanks for filling this form", "text/plain"); } } else if (!string.IsNullOrEmpty(Request["prev"])) { // Even if validation failed we allow the user to // navigate to previous steps publish.CurrentStepIndex--; } return View(publish); } 

所以我的问题是,我将在哪里填写Step2的列表? 我的第一个想法是在Step2视图模型中有一个构造函数。 第二个想法是在控制器中找到一些逻辑,找出哪个步骤,并从那里填充它。 但这听起来有点糟糕。

从控制器填充。 总是。 您永远不应该在视图模型内部或者更糟的是与实体交互。 如果要抽象数据库工作,请将其移动到存储库或服务,然后让控制器调用该方法。

我最后结束了这一切。 但我真的很想得到一些关于这种方法的反馈。 例如,我怎么能将这个控制器混乱移动到自定义模型绑定器中?

片段

  if (publish.Steps[publish.CurrentStepIndex].GetType() == typeof(Step1ViewModel)) { var model = publish.Steps[publish.CurrentStepIndex] as Step1ViewModel; // Do some magic } 

完整代码

  [HttpPost] [ValidateAntiForgeryToken] public ActionResult Publish([Deserialize] PublishViewModel publish, IStepViewModel step) { publish.Steps[publish.CurrentStepIndex] = step; if (ModelState.IsValid) { if (!string.IsNullOrEmpty(Request["next"])) publish.CurrentStepIndex++; else if (!string.IsNullOrEmpty(Request["prev"])) publish.CurrentStepIndex--; } else if (!string.IsNullOrEmpty(Request["prev"])) { publish.CurrentStepIndex--; } if (publish.Steps[publish.CurrentStepIndex].GetType() == typeof(Step1ViewModel)) { var model = publish.Steps[publish.CurrentStepIndex] as Step1ViewModel; // Do some magic } else if (publish.Steps[publish.CurrentStepIndex].GetType() == typeof(Step2ViewModel)) { var model = publish.Steps[publish.CurrentStepIndex] as Step2ViewModel; // Do some magic } return View(publish); }