使用编辑器模板显示多个表单

本文关键字:表单 显示 编辑器 | 更新日期: 2023-09-27 18:25:18

我的问题与这个问题非常相似。我正在开发的应用程序是用MVC 3和Razor编写的。它允许用户从商店中选择商品,并将每个商品发送到不同的地址。

以下是我的ViewModels:

public class DeliveryDetailsViewModel
{
    public FromDetailsViewModel From { get; set; }
    public IList<ToDetailsViewModel> To { get; set; }
}
public class DetailsViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}
public class FromDetailsViewModel : DetailsViewModel
{
    public string StreetAddress { get; set; }
    public string Suburb { get; set; }
    public string Postcode { get; set; }
}
public class ToDetailsViewModel : DetailsViewModel
{
    public string Message { get; set; }
}

我的视图与下面类似。

@model Store.ViewModels.DeliveryDetailsViewModel
@Html.EditorFor(m => m.From)
@Html.EditorFor(m => m.To)

我的意图是显示一组表格(购物车中的每个项目一个),使用户可以在其中键入不同的送货详细信息。每个表格都有自己的提交按钮。

呈现"To"表单的编辑器模板如下:

@model Store.ViewModels.ToDetailsViewModel
@using (Html.BeginForm("ConfirmTo", "Delivery"))
{
    @Html.TextBoxFor(m => m.FirstName)
    @Html.TextBoxFor(m => m.LastName)
    @Html.TextBoxFor(m => m.Email)
    @Html.TextBoxFor(m => m.Message)
    <input type="submit" value="Confirm" />
}

我的控制器:

public class DeliveryController : Controller
{
    public ActionResult Index()
    {
        var model = new DeliveryDetailsViewModel();
        model.From = new FromDetailsViewModel();
        model.To = new List<ToDetailsViewModel>();
        return View(model);
    }
    public ActionResult ConfirmTo(ToDetailsViewModel toDetails)
    {
        // Save to database.
    }
}

我有几个问题:

  1. "to"编辑器模板没有呈现任何内容(尽管它过去是这样)。它指出模型类型不匹配(即ToDetailsViewModelList<ToDetailsViewModel>不同),尽管我认为编辑器模板应该将索引附加到输入字段名以实现正确的绑定。

  2. 单击Confirm并提交To列表中的第一个表单时,控制器将接收具有正确绑定的视图模型。提交以下任何表单(索引为1或更高)将调用ConfirmTo操作并传递一个为null的ToDetailsViewModel

如有任何帮助,我们将不胜感激。如果您想了解有关我遇到的问题或我使用的代码的更多信息,请随时询问。

使用编辑器模板显示多个表单

1) "to"编辑器模板没有呈现任何

在控制器操作中,您没有在列表中放入任何内容。你刚刚实例化了它。所以放一些元素:

model.To = new List<ToDetailsViewModel>();
model.To.Add(new ToDetailsViewModel());
model.To.Add(new ToDetailsViewModel());
...

2) 单击Confirm并提交To列表中的第一个表单时,控制器将接收具有正确绑定的视图模型。提交以下任何表单(索引为1或更高)将调用ConfirmTo操作并传递一个为null的ToDetailsViewModel。

如果这甚至适用于第一个元素,我会感到惊讶,因为输入字段当前没有正确的名称。它们都以To[someIndex]为前缀,而ConfirmTo需要一个平面模型,而不是集合。

因此,您可以将前缀设置为空字符串,以便在~/Views/Shared/EditorTemplates/ToDetailsViewModel.cshtml编辑器模板中生成正确的输入元素:

@model ToDetailsViewModel
@{
    ViewData.TemplateInfo.HtmlFieldPrefix = "";
}
@using (Html.BeginForm("ConfirmTo", "Home"))
{
    @Html.TextBoxFor(m => m.FirstName)
    @Html.TextBoxFor(m => m.LastName)
    @Html.TextBoxFor(m => m.Email)
    @Html.TextBoxFor(m => m.Message)
    <input type="submit" value="Confirm" />
}

1)您尝试过吗,因为您的视图模型具有

public IList<ToDetailsViewModel> To { get; set; }

To是一个列表,因此您的编辑器模板应该有

@model IEnumerable<Store.ViewModels.ToDetailsViewModel>

模板应该使用foreach

@foreach(model in Model){}