使用 EF 动态添加的表单数据未绑定到回发 .net 框架 4.7.2 MCV
Dynamically added form data not binding on postback .net framework 4.7.2 MCV using EF
我有一个包含动态对象数组的模型。这个对象只有一个开始日期时间、结束日期时间和一个表示槽数的整数。
我正在使用 MVC、EF 和 .net 4.7.2
我最终想做的是允许用户(使用js)将多条记录添加到table。这有效!
什么是回发,数组没有绑定到数组。
我做错了什么?
我有 2 个模型:
public class testmodel
{
[Required]
public DateTime StartDateTime { get; set; }
[Required]
public DateTime EndDateTime { get; set; }
public int? NumberOfSlots { get; set; }
}
public class testMainModel
{
public List<testmodel> AllDates { get; set; }
}
控制器:
public async Task<ActionResult> TestShifts()
{
Models.testMainModel model = new Models.testMainModel();
List<Models.testmodel> testDates = new List<Models.testmodel>();
model.AllDates = testDates;
return View(model) ;
}
[HttpPost]
public async Task<ActionResult> TestShifts(Models.testMainModel model)
{
var x = model;
var y = 1;
return View(model);
}
查看:
@model WCSOReserves.Models.testMainModel
@{
ViewBag.Title = "TestShifts";
}
<h2>TestShifts</h2>
@using (Html.BeginForm("TestShifts", "Events", FormMethod.Post))
{
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Start Date/Time</th>
<th>End Date/Time</th>
<th></th>
</tr>
</thead>
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count - 1)">
@for (int i = 0; i < Model.AllDates.Count; i++)
{
<tr data-id="@i">
<td>
<input asp-for="@Model.AllDates[i].StartDateTime" class="form-control" />
</td>
<td>
<input asp-for="@Model.AllDates[i].EndDateTime" class="form-control" />
</td>
<td>
<button type="button" class="btn btn-sm btn-danger">
<i class="align-middle me-2 fas fa-fw fa-trash-alt"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
<div>
<button type="button" class="btn btn-secondary" id="addDateTime">Add Shift</button>
</div>
<div>
<input type="submit" class="btn btn-primary" id="Submit" value="Submit" />
</div>
</div>
}
@section Scripts{
<script>
$(document).ready(function () {
$('button#addDateTime').on('click', function() {
var countVal = parseInt($('#eventDateTimes').attr('data-event-dates-start-count'));
countVal += 1;
var inputStartDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The Start Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__StartDateTime')
.attr('name', 'testMainModel.AllDates[' + countVal + '].StartDateTime').addClass('form-control');
var inputEndDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The End Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__EndDateTime')
.attr('name', 'testMainModel.AllDates[' + countVal + '].EndDateTime').addClass('form-control');
var button = $('<button />').attr('type', 'button').addClass('btn btn-sm btn-danger')
.append($('<i />').addClass('align-middle me-2 fas fa-fw fa-trash-alt'));
var row = $('<tr />')
.attr('data-id', countVal)
.append($('<td />').append(inputStartDate))
.append($('<td />').append(inputEndDate))
.append($('<td />').append(button));
$('#eventDateTimes').append(row);
$('#eventDateTimes').attr('data-event-dates-start-count', countVal);
});
$(document).on('click',
'#eventDateTimes tr td button',
function() {
$('tr[data-id="' + $(this).parent().parent().attr('data-id') + '"]').remove();
});
});
</script>
js 有效,我可以动态添加行。但是,在回发时,模型是空的。
这里data-event-dates-start-count
应该和总数一样。
尝试
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count)">
而不是
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count - 1)">
js works, I can add rows dynamically. However, on postback, the model is empty.
不仅是你的 post 背部。您甚至无法在导致 post返回空模型的后端接收模型。
模型绑定系统通过名称属性绑定 属性。您的前端名称属性类似于 testMainModel.AllDates[index].PropertyName
,与后端不匹配。
一个简单的方法是更改您的 post 操作参数名称,如下所示:
[HttpPost]
public async Task<ActionResult> TestShifts(Models.testMainModel testMainModel)
{
var x = testMainModel;
var y = 1;
return View(testMainModel);
}
另一种方法是,您可以将 name
从 testMainModel.AllDates[index].PropertyName
更改为 AllDates[index].PropertyName
。这样你就不需要改变动作参数了。
var inputStartDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The Start Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__StartDateTime')
.attr('name', 'AllDates[' + countVal + '].StartDateTime').addClass('form-control');
var inputEndDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The End Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__EndDateTime')
.attr('name', 'AllDates[' + countVal + '].EndDateTime').addClass('form-control');
另外,ASP.NET没有标签助手,它使用Html助手。 Tag Helper 存在于 ASP.NET Core 中。所以如果你使用 ASP.NET,你需要更改下面的 html 代码:
<td>
@Html.EditorFor(model => Model.AllDates[i].StartDateTime, new { htmlAttributes = new { @class = "form-control",@type= "datetime-local" } })
</td>
<td>
@Html.EditorFor(model => Model.AllDates[i].EndDateTime, new { htmlAttributes = new { @class = "form-control", @type = "datetime-local" } })
</td>
我有一个包含动态对象数组的模型。这个对象只有一个开始日期时间、结束日期时间和一个表示槽数的整数。
我正在使用 MVC、EF 和 .net 4.7.2
我最终想做的是允许用户(使用js)将多条记录添加到table。这有效!
什么是回发,数组没有绑定到数组。
我做错了什么?
我有 2 个模型:
public class testmodel
{
[Required]
public DateTime StartDateTime { get; set; }
[Required]
public DateTime EndDateTime { get; set; }
public int? NumberOfSlots { get; set; }
}
public class testMainModel
{
public List<testmodel> AllDates { get; set; }
}
控制器:
public async Task<ActionResult> TestShifts()
{
Models.testMainModel model = new Models.testMainModel();
List<Models.testmodel> testDates = new List<Models.testmodel>();
model.AllDates = testDates;
return View(model) ;
}
[HttpPost]
public async Task<ActionResult> TestShifts(Models.testMainModel model)
{
var x = model;
var y = 1;
return View(model);
}
查看:
@model WCSOReserves.Models.testMainModel
@{
ViewBag.Title = "TestShifts";
}
<h2>TestShifts</h2>
@using (Html.BeginForm("TestShifts", "Events", FormMethod.Post))
{
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Start Date/Time</th>
<th>End Date/Time</th>
<th></th>
</tr>
</thead>
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count - 1)">
@for (int i = 0; i < Model.AllDates.Count; i++)
{
<tr data-id="@i">
<td>
<input asp-for="@Model.AllDates[i].StartDateTime" class="form-control" />
</td>
<td>
<input asp-for="@Model.AllDates[i].EndDateTime" class="form-control" />
</td>
<td>
<button type="button" class="btn btn-sm btn-danger">
<i class="align-middle me-2 fas fa-fw fa-trash-alt"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
<div>
<button type="button" class="btn btn-secondary" id="addDateTime">Add Shift</button>
</div>
<div>
<input type="submit" class="btn btn-primary" id="Submit" value="Submit" />
</div>
</div>
}
@section Scripts{
<script>
$(document).ready(function () {
$('button#addDateTime').on('click', function() {
var countVal = parseInt($('#eventDateTimes').attr('data-event-dates-start-count'));
countVal += 1;
var inputStartDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The Start Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__StartDateTime')
.attr('name', 'testMainModel.AllDates[' + countVal + '].StartDateTime').addClass('form-control');
var inputEndDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The End Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__EndDateTime')
.attr('name', 'testMainModel.AllDates[' + countVal + '].EndDateTime').addClass('form-control');
var button = $('<button />').attr('type', 'button').addClass('btn btn-sm btn-danger')
.append($('<i />').addClass('align-middle me-2 fas fa-fw fa-trash-alt'));
var row = $('<tr />')
.attr('data-id', countVal)
.append($('<td />').append(inputStartDate))
.append($('<td />').append(inputEndDate))
.append($('<td />').append(button));
$('#eventDateTimes').append(row);
$('#eventDateTimes').attr('data-event-dates-start-count', countVal);
});
$(document).on('click',
'#eventDateTimes tr td button',
function() {
$('tr[data-id="' + $(this).parent().parent().attr('data-id') + '"]').remove();
});
});
</script>
js 有效,我可以动态添加行。但是,在回发时,模型是空的。
这里data-event-dates-start-count
应该和总数一样。
尝试
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count)">
而不是
<tbody id="eventDateTimes" data-event-dates-start-count="@(Model.AllDates.Count - 1)">
js works, I can add rows dynamically. However, on postback, the model is empty.
不仅是你的 post 背部。您甚至无法在导致 post返回空模型的后端接收模型。
模型绑定系统通过名称属性绑定 属性。您的前端名称属性类似于 testMainModel.AllDates[index].PropertyName
,与后端不匹配。
一个简单的方法是更改您的 post 操作参数名称,如下所示:
[HttpPost]
public async Task<ActionResult> TestShifts(Models.testMainModel testMainModel)
{
var x = testMainModel;
var y = 1;
return View(testMainModel);
}
另一种方法是,您可以将 name
从 testMainModel.AllDates[index].PropertyName
更改为 AllDates[index].PropertyName
。这样你就不需要改变动作参数了。
var inputStartDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The Start Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__StartDateTime')
.attr('name', 'AllDates[' + countVal + '].StartDateTime').addClass('form-control');
var inputEndDate = $('<input />').attr('type', 'datetime-local').attr('data-val', 'true')
.attr('data-val-required', 'The End Date Field is required.')
.attr('id', 'testMainModel_AllDates_' + countVal + '__EndDateTime')
.attr('name', 'AllDates[' + countVal + '].EndDateTime').addClass('form-control');
另外,ASP.NET没有标签助手,它使用Html助手。 Tag Helper 存在于 ASP.NET Core 中。所以如果你使用 ASP.NET,你需要更改下面的 html 代码:
<td>
@Html.EditorFor(model => Model.AllDates[i].StartDateTime, new { htmlAttributes = new { @class = "form-control",@type= "datetime-local" } })
</td>
<td>
@Html.EditorFor(model => Model.AllDates[i].EndDateTime, new { htmlAttributes = new { @class = "form-control", @type = "datetime-local" } })
</td>