当我发送包含多个具有不同模型的局部视图的视图时,控制器应该接收什么?

What the controller should receive when I am sending a view that contains multiple partial view with different models?

当我发送一个包含多个不同模型的局部视图的视图时,控制器应该接收什么。

我有一个视图呈现 multiple/dynamic 个局部视图(这些视图是根据用户之前选择的包来选择的),所有这些局部视图都有不同的模型,我需要将它们集中在一起提交大 "parent" 形式。我主要关心的是控制器应该接收什么?以及如何处理表单中的所有信息,因为我有多个可变模型(取决于用户选择的模型)从表单发送。

这是我的父视图,根据用户选择的包呈现所有部分视图(即父视图可以呈现 1 到 7 个表单。它们都有不同的模型)。 IEnumerable string 包含一个字符串列表,我将使用它来吐出一个带有视图和模型的字典,以便稍后在此视图中呈现它们。

@using UI.Shared.Utils
@model IEnumerable<string>
@{
  var forms = CustomFormUtil.GetCustomMetaPartial(Model);       
}                    
@using (Html.BeginForm(MVC.Service.NewOrderRequest.Index(**I am confused what to pass here**), FormMethod.Post))
{
  foreach (var form in forms)
  {
    { Html.RenderPartial(form.View, form.Model); }
  }
  <p style="clear: both">
    <input id="submitNOR" type="submit" value="Submit" style="float: right" />
  </p>
}

假设用户填写了 4 个局部视图,这意味着我必须向控制器发送 4 个不同的模型,以便我可以使用用户填写的数据。

这是我的控制器:

[HttpPost]
[SaveModelState]
public virtual RedirectToRouteResult Index(**What should I receive**)
{
  if (!ModelState.IsValid)
  {
    ModelState.AddModelError("error", "Please fill out the required fields");
    return RedirectToAction(MVC.Service.NewOrderRequestForms.Index());
  }
  ...
}

我主要关心的是控制器应该接收什么?我尝试了以下方法:

[HttpPost]
[SaveModelState]
public virtual RedirectToRouteResult Index(IEnumerable<ICustomModel> models)

但经过一些研究,这是不可能的,我也尝试将所有可能的模型传递给控制器​​

[HttpPost]
[SaveModelState]
public virtual RedirectToRouteResult Index(Model1 model1, ..., ModelN modeln)

这也不行,我最近的尝试是创建一个包含所有可能模型的主模型并将其传递给控制器​​,这是我的主模型

namespace UI.Next.Areas.Service.Models
{
  public class TdlMasterModel : ICustomMetaModel
  {
    public TdlMasterModel()
    {
    }
    public TdlMasterModel(Guid? accountId)
    {
      AccountId = accountId;
    }
    public Guid? AccountId { get; set; }
    public Model1 model1{ get; set; }
    ...
    public ModelN modeln{ get; set; }
  }
}

控制器:

[HttpPost]
[SaveModelState]
public virtual RedirectToRouteResult Index(MasterModel masterModel)

到目前为止,所提出的解决方案都没有奏效。 有没有直接的解决方案,或者我将不得不创建一个 ModelBinder 来处理这个问题。

使用包含要呈现的每个表单的模型的视图模型

查看模型

public class MasterVM
{
  public Model1 Model1 { get; set; }
  public Model2 Model2 { get; set; }
  ....
}

控制器

public ActionResult Index()
{
  MasterVM model = new MasterVM();
  // Set the values of only those models you want to display forms for
  model.Model2 = new Model2();
  return View(model);
}

[HttpPost]
public ActionResult Index(MasterVM model)
{
  if(!ModelState.IsValid)
  {
    return View();
  }
  if (model.Model1 != null)
  {
    // save Model1
  }
  else if (model.Model2 != null)
  {
    // save Model2
  }
  ....
  // redirect somewhere
}

部分_Model1.cshtml

@model Model1

@Html.LabelFor(m => m.SomeProperty)
@Html.TextBoxFor(m => m.SomeProperty)
@Html.ValidationMessageFor(m => m.SomeProperty)

@Html.LabelFor(m => m.AnotherProperty)
@Html.TextBoxFor(m => m.AnotherProperty)
@Html.ValidationMessageFor(m => m.AnotherProperty)

....

查看

@model MasterVM
@using Html.BeginForm())
{
  if(Model.Model1 != null)
  {
    @Html.Partial("_Model1", Model.Model1, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Model1" }})
  }
  if(Model.Model2 != null)
  {
    @Html.Partial("_Model2", Model.Model2, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Model2" }})
  }
  ....
  <input type="submit" />
}

注意@Html.Partial的第三个参数。这将为控件名称添加前缀,因此如果 Model1 包含 属性 string Name,控件将生成为 <input name="Model1.Name" ...> 允许您 post 返回和绑定到 MasterVM