将MVC4绑定到包含数组的对象

时间:2014-03-03 11:19:17

标签: c# asp.net-mvc-4

我正在创建一个表单,允许员工在线提交时间表。表单由许多部分组成,每个部分代表一周中的某一天。在每个部分中,用户可以添加多行,每行反映当天进行的任务。

function AddRow(day)
{
    var count = $("#RowCount_" + day).data("count");

    var row = "<tr>" +
                   "<td>&nbsp;</td>" +
                    "<td><input type='text' size='50' id='" + day + "[" + count + "].Description' name='timesheet." + day + "[" + count + "].Description' class='Description' data-day='" + day + "' /></td>" +
                    "<td><input type='text' size='6' id='" + day + "[" + count + "].Start' name='timesheet." + day + "[" + count + "].Start' /></td>" +
                    "<td><input type='text' size='6' id='" + day + "[" + count + "].Finish' name='timesheet." + day + "[" + count + "].Finish' /></td>" +
                    "<td><input type='text' size='6' id='" + day + "[" + count + "].Travel' name='timesheet." + day + "[" + count + "].Travel'/></td>" +
                    "<td>" +
                        "<select style='width:200px' id='" + day + "[" + count + "].JobNo' name='timesheet." + day + "[" + count + "].JobNo'>@Html.Raw(ViewBag.Jobs)</select>" +
                    "</td>" +
                    "<td><input type='text' size='6' id='" + day + "[" + count + "].Hrs' name='timesheet." + day + "[" + count + "].Hrs' /></td>" +
                "</tr>";

    $("#Table_" + day).append(row);
    $("#RowCount_" + day).data("count", ++count);
}

然后我想将它绑定到Timesheet对象,如下所示:

public class Timesheet
{
    List<Core.Models.TimesheetEntry> Monday = new List<TimesheetEntry>();
    TimesheetEntry[] Tuesday { get; set; }
    TimesheetEntry[] Wednesday { get; set; }
    TimesheetEntry[] Thursday { get; set; }
    TimesheetEntry[] Friday { get; set; }
    TimesheetEntry[] Saturday { get; set; }
    TimesheetEntry[] Sunday { get; set; }
}

(注意我在这里尝试了两个列表和数组,两者都没有绑定,但一分钟内更多)

TimesheetEntry如下:

public class TimesheetEntry
{
    public string Description { get; set; }
    public string Start { get; set; }
    public string Finish { get; set; }
    public decimal Travel { get; set; }
    public string JobNo { get; set; }
    public decimal Hrs { get; set; }
}

这会发布到以下控制器方法:

[HttpPost]
public ActionResult Create(Core.Models.Timesheet timesheet)
{
    return View();
}

提交时,表单不绑定(时间表中的所有字段均为0或null)。但是,如果我将控制器更改为

public ActionResult Create(List<Core.Models.TimesheetEntry> Monday)
{
    return View();
}

并将html字段的名称调整为name='" + day + "[" + count + "].Description'然后它就会很好地绑定。这有点乱,所以如果可能的话我宁愿使用Timesheet类。是否存在绑定到模型中列表的问题?

编辑:下面是一个帖子数据片段,周一有一个条目和2个空白条目,星期二有3个空白:

timesheet.Monday[0].Description:test entry
timesheet.Monday[0].Start:0900
timesheet.Monday[0].Finish:1700
timesheet.Monday[0].Travel:0
timesheet.Monday[0].JobNo:14089A - line 14 hut heater sockets
timesheet.Monday[0].Hrs:7.5
timesheet.Monday[1].Description:
timesheet.Monday[1].Start:
timesheet.Monday[1].Finish:
timesheet.Monday[1].Travel:
timesheet.Monday[1].JobNo:14089A - line 14 hut heater sockets
timesheet.Monday[1].Hrs:
timesheet.Monday[2].Description:
timesheet.Monday[2].Start:
timesheet.Monday[2].Finish:
timesheet.Monday[2].Travel:
timesheet.Monday[2].JobNo:14089A - line 14 hut heater sockets
timesheet.Monday[2].Hrs:
timesheet.Tuesday[0].Description:
timesheet.Tuesday[0].Start:
timesheet.Tuesday[0].Finish:
timesheet.Tuesday[0].Travel:
timesheet.Tuesday[0].JobNo:14089A - line 14 hut heater sockets
timesheet.Tuesday[0].Hrs:
timesheet.Tuesday[1].Description:
timesheet.Tuesday[1].Start:
timesheet.Tuesday[1].Finish:
timesheet.Tuesday[1].Travel:
timesheet.Tuesday[1].JobNo:14089A - line 14 hut heater sockets
timesheet.Tuesday[1].Hrs:

2 个答案:

答案 0 :(得分:0)

将所有TimesheetEntry[]数组更改为List<TimesheetEntry>

尝试将constuctor添加到初始化模型的所有字段的模型中:

public class Timesheet
{
    public Timesheet()
    {
        Monday = new List<Core.Models.TimesheetEntry>();
        Tuesday  = new List<Core.Models.TimesheetEntry>();          
    }   
}

确保您的帖子数据的前缀如Timesheet.Monday[0].Description=...

这就是做事

答案 1 :(得分:0)

回答这个问题只要对博客文章有好处。无论如何,请执行以下操作

转到Views-&gt;共享文件夹,然后创建一个名为EditorTemplates

的新文件夹

在该EditorTemplates文件夹中,创建一个名为_TimeSheetEntry的局部视图,它处理一行(一个TimeSheetEntry),如下所示

@model TimeSheetEntry
<tr>
    <td></td>
    <td>@Html.TextBoxFor(model => model.Description)</td>
    <!--Add code for other fields-->
</tr>

现在在主视图中,执行以下操作。

@model TimeSheet
<table id="table_1">
    @for (var i = 0; i < Model.Monday.Count; i++)
    {
        @Html.EditorFor(model => model.Monday[i], "_TimeSheetEntry")
    }
</table>
<input type="button" onClick="addRow(1)" value="Add Row" />
<!-- Do the same for other 4 days, change the table id accordingly and pass the correct day value for addRow-->

现在在你的控制器中,创建一个Action,它将向表中添加一个新行,稍后我们将使用ajax调用它。

[HttpGet]
public PartialViewResult AddTimeSheetRow(int day, int index)
{
    string prefix = "";
    switch(day)
    {
        case 1:
        prefix = "Monday[" + index + "]"
        break;
        //do the same for other 4 days but change the day name
    }
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
    return PartialView("_TimeSheetEntry", new TimeSheetEntry());
}

现在,让我们转到Create视图中的javascript代码。

function addRow(day){
    var tbody = $("table_" + day).find('tbody');
    var index = tbody.find('tr').size() - 1;
    $.get('@Url.Action("AddTimeSheetRow", "YourControllerName")', 
          { day:day, index:index },
          function (response){
              tbody.append(response);
          });
}

这是我放在一起的快速代码,肯定有改进的余地。但上面应该让你开始。