Form POST 对于 MVC Model Binder 来说是否太大
Can a Form POST be too large for MVC Model Binder
此问题出现在.net core 3.1 MVC网站。
我无法让我的 POST 绑定到我的控制器操作(参数始终为空)。数据是从数据库加载的,是一个大的递归结构。
如果我在数据库中删除几百行 JSON(大约 2500 行),它将绑定 OK。
GET 显示完美。
即使我将我的 Action 方法参数从我的 ViewModel 更改为 IFormCollection,它仍然以 null 形式出现。这里有一些我不知道的限制吗?
如果大小是问题,是否有更好的方法 POSTing 数据?
父视图
<form id="frmAdditionalCodes" name="frmAdditionalCodes" method="post">
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Code)
</th>
<th>
@Html.DisplayNameFor(model => model.FullName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.Code)
<input asp-for="@Model.Code" class="form-control" style="display:none" />
</td>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.FullName)
<input asp-for="@Model.FullName" class="form-control" style="display:none" />
</td>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.Description)
<input asp-for="@Model.Description" class="form-control" style="display:none" />
</td>
<td style="width:20px">
<span>
<i id="addTagItem" class="fas fa-folder-plus" title="Add child item"></i>
</span>
</td>
<td>
<partial name="~/Views/PartialViews/_SectionsAndTags.cshtml" model="@Model.Entities" view-data="ViewData" />
</td>
<td>
</td>
</tr>
</tbody>
</table>
</form>
子视图
<table class="partial_table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Code)
</th>
<th>
@Html.DisplayNameFor(model => model.FullName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th colspan="2">
@Html.DisplayNameFor(model => model.Entities)
</th>
</tr>
</thead>
<tbody>
@{ List<CdsDeclarationSectionAndTagItemViewModel> list = Model.ToList();
for (int i = 0; i < list.Count(); i++)
{
<tr>
@{
string elementNameCode = $"{list[i].Prefix}Code";
string elementNameFullName = $"{list[i].Prefix}FullName";
string elementNameDescription = $"{list[i].Prefix}Description";
string elementNameIsDeleted = $"{list[i].Prefix}IsDeleted";
}
<td>
<span>@list[i].Code</span>
<input asp-for="@list[i].Code" name="@elementNameCode" class="form-control" style="display: none" />
</td>
<td>
<span>@list[i].FullName</span>
<input asp-for="@list[i].FullName" class="form-control" name="@elementNameFullName" style="display: none" />
</td>
<td>
<span>@list[i].Description</span>
<input asp-for="@list[i].Description" class="form-control" name="@elementNameDescription" style="display: none" />
</td>
<td>
@if (list[i].Entities?.Length > 0)
{<img id="collapseItem" state="expanded" width="20" height="20" src="~/images/minus_PNG24.png" />
}
<span>
<i id="editTagItem" class="fas fa-pencil-alt" title="Edit item"></i>
<i id="deleteTagItem" class="far fa-trash-alt" title="Delete item"></i>
<i id="addTagItem" class="fas fa-folder-plus" title="Add child item"></i>
<i id="updateTagItem" class="far fa-save" title="Save changes" style="display: none"></i>
<i id="cancelTagItem" class="fas fa-undo-alt" title="Undo changes" style="display: none"></i>
</span>
</td>
<td>
@if (list[i].Entities?.Length > 0)
{
<partial name="~/Views/PartialViews/_SectionsAndTags.cshtml" model="@list[i].Entities" />
}
</td>
<td>
<input type="hidden" value="false" name="@elementNameIsDeleted" />
</td>
</tr>
}
}
</tbody>
</table>
ViewModel
public class CdsDeclarationSectionAndTagViewModel
{
public string Code { get; set; }
public string FullName { get; set; }
public string Description { get; set; }
public CdsDeclarationSectionAndTagItemViewModel[] Entities { get; set; }
}
public class CdsDeclarationSectionAndTagItemViewModel
{
public string Code { get; set; }
public string FullName { get; set; }
public string Description { get; set; }
public CdsDeclarationSectionAndTagItemViewModel[] Entities { get; set; }
public string Prefix { get; set; }
public bool IsDeleted { get; set; }
}
控制器
这里 vm 是空的,除非我删除一些数据
[HttpPost]
public async Task<IActionResult> CdsDeclarationSectionAndTag(CdsDeclarationSectionAndTagViewModel vm)
{
}
如果我这样改,fc也是null
[HttpPost]
public async Task<IActionResult> CdsDeclarationSectionAndTag(IFormCollection fc)
{
}
发布的表单数据如下所示(最终可以有 4 或 5 个递归级别)
Code: 42A
FullName:
Description: Declaration
Entities[0].Code: 023
Entities[0].FullName: Acceptance (taxpoint) datetime
Entities[0].Description: Acceptance (taxpoint) datetime
Entities[0].IsDeleted: false
Entities[1].Code: D026
Entities[1].FullName: LRN
Entities[1].Description: LRN
Entities[1].IsDeleted: false
Entities[2].Code: D013
Entities[2].FullName: Declaration type
Entities[2].Description: Declaration type
Entities[2].IsDeleted: false
Entities[3].Code: 109
Entities[3].FullName: Invoice total
Entities[3].Description: Invoice total
Entities[3].IsDeleted: false
Entities[4].Code: 504
Entities[4].FullName: Specific circumstances indicator
Entities[4].Description: Specific circumstances indicator
Entities[4].IsDeleted: false
Entities[5].Code: 131
Entities[5].FullName: Gross mass
Entities[5].Description: Gross mass
Entities[5].IsDeleted: false
Entities[6].Code: 146
Entities[6].FullName: Total packages
Entities[6].Description: Total packages
Entities[6].IsDeleted: false
Entities[7].Code: 61B
Entities[7].FullName: Authentication
Entities[7].Description: Authentication
Entities[7].Entities[0].Code: 104
Entities[7].Entities[0].FullName: Signature/Authentication
Entities[7].Entities[0].Description: Signature/Authentication
Entities[7].Entities[0].IsDeleted: false
Entities[7].IsDeleted: false
Entities[8].Code: 02A
Entities[8].FullName: Deferred Payment
Entities[8].Description: Deferred Payment
Entities[8].Entities[0].Code: D031
Entities[8].Entities[0].FullName: Deferment category code
Entities[8].Entities[0].Description: Category code
Entities[8].Entities[0].IsDeleted: false
Entities[8].Entities[1].Code: D005
Entities[8].Entities[1].FullName: Deferment ID
Entities[8].Entities[1].Description: ID
Entities[8].Entities[1].IsDeleted: false
Entities[8].Entities[2].Code: D006
Entities[8].Entities[2].FullName: Deferment Type
Entities[8].Entities[2].Description: Type
Entities[8].Entities[2].IsDeleted: false
Entities[8].IsDeleted: false
Entities[9].Code: 03A
Entities[9].FullName: Additional Information
Entities[9].Description: Additional Information
Entities[9].Entities[0].Code: 226
Entities[9].Entities[0].FullName: Additional Information Statement code
Entities[9].Entities[0].Description: Statement code
Entities[9].Entities[0].IsDeleted: false
....
我在 线程上找到了答案。
事实证明,默认情况下,您可以提交的表单值限制为 1024。
我在Startup.cs中使用了以下代码来更改限制,问题已经解决,现在可以成功绑定
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
});
此问题出现在.net core 3.1 MVC网站。
我无法让我的 POST 绑定到我的控制器操作(参数始终为空)。数据是从数据库加载的,是一个大的递归结构。 如果我在数据库中删除几百行 JSON(大约 2500 行),它将绑定 OK。
GET 显示完美。
即使我将我的 Action 方法参数从我的 ViewModel 更改为 IFormCollection,它仍然以 null 形式出现。这里有一些我不知道的限制吗? 如果大小是问题,是否有更好的方法 POSTing 数据?
父视图
<form id="frmAdditionalCodes" name="frmAdditionalCodes" method="post">
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Code)
</th>
<th>
@Html.DisplayNameFor(model => model.FullName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.Code)
<input asp-for="@Model.Code" class="form-control" style="display:none" />
</td>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.FullName)
<input asp-for="@Model.FullName" class="form-control" style="display:none" />
</td>
<td style="width:50px">
@Html.DisplayFor(modelItem => Model.Description)
<input asp-for="@Model.Description" class="form-control" style="display:none" />
</td>
<td style="width:20px">
<span>
<i id="addTagItem" class="fas fa-folder-plus" title="Add child item"></i>
</span>
</td>
<td>
<partial name="~/Views/PartialViews/_SectionsAndTags.cshtml" model="@Model.Entities" view-data="ViewData" />
</td>
<td>
</td>
</tr>
</tbody>
</table>
</form>
子视图
<table class="partial_table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Code)
</th>
<th>
@Html.DisplayNameFor(model => model.FullName)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th colspan="2">
@Html.DisplayNameFor(model => model.Entities)
</th>
</tr>
</thead>
<tbody>
@{ List<CdsDeclarationSectionAndTagItemViewModel> list = Model.ToList();
for (int i = 0; i < list.Count(); i++)
{
<tr>
@{
string elementNameCode = $"{list[i].Prefix}Code";
string elementNameFullName = $"{list[i].Prefix}FullName";
string elementNameDescription = $"{list[i].Prefix}Description";
string elementNameIsDeleted = $"{list[i].Prefix}IsDeleted";
}
<td>
<span>@list[i].Code</span>
<input asp-for="@list[i].Code" name="@elementNameCode" class="form-control" style="display: none" />
</td>
<td>
<span>@list[i].FullName</span>
<input asp-for="@list[i].FullName" class="form-control" name="@elementNameFullName" style="display: none" />
</td>
<td>
<span>@list[i].Description</span>
<input asp-for="@list[i].Description" class="form-control" name="@elementNameDescription" style="display: none" />
</td>
<td>
@if (list[i].Entities?.Length > 0)
{<img id="collapseItem" state="expanded" width="20" height="20" src="~/images/minus_PNG24.png" />
}
<span>
<i id="editTagItem" class="fas fa-pencil-alt" title="Edit item"></i>
<i id="deleteTagItem" class="far fa-trash-alt" title="Delete item"></i>
<i id="addTagItem" class="fas fa-folder-plus" title="Add child item"></i>
<i id="updateTagItem" class="far fa-save" title="Save changes" style="display: none"></i>
<i id="cancelTagItem" class="fas fa-undo-alt" title="Undo changes" style="display: none"></i>
</span>
</td>
<td>
@if (list[i].Entities?.Length > 0)
{
<partial name="~/Views/PartialViews/_SectionsAndTags.cshtml" model="@list[i].Entities" />
}
</td>
<td>
<input type="hidden" value="false" name="@elementNameIsDeleted" />
</td>
</tr>
}
}
</tbody>
</table>
ViewModel
public class CdsDeclarationSectionAndTagViewModel
{
public string Code { get; set; }
public string FullName { get; set; }
public string Description { get; set; }
public CdsDeclarationSectionAndTagItemViewModel[] Entities { get; set; }
}
public class CdsDeclarationSectionAndTagItemViewModel
{
public string Code { get; set; }
public string FullName { get; set; }
public string Description { get; set; }
public CdsDeclarationSectionAndTagItemViewModel[] Entities { get; set; }
public string Prefix { get; set; }
public bool IsDeleted { get; set; }
}
控制器 这里 vm 是空的,除非我删除一些数据
[HttpPost]
public async Task<IActionResult> CdsDeclarationSectionAndTag(CdsDeclarationSectionAndTagViewModel vm)
{
}
如果我这样改,fc也是null
[HttpPost]
public async Task<IActionResult> CdsDeclarationSectionAndTag(IFormCollection fc)
{
}
发布的表单数据如下所示(最终可以有 4 或 5 个递归级别)
Code: 42A FullName: Description: Declaration Entities[0].Code: 023 Entities[0].FullName: Acceptance (taxpoint) datetime Entities[0].Description: Acceptance (taxpoint) datetime Entities[0].IsDeleted: false Entities[1].Code: D026 Entities[1].FullName: LRN Entities[1].Description: LRN Entities[1].IsDeleted: false Entities[2].Code: D013 Entities[2].FullName: Declaration type Entities[2].Description: Declaration type Entities[2].IsDeleted: false Entities[3].Code: 109 Entities[3].FullName: Invoice total Entities[3].Description: Invoice total Entities[3].IsDeleted: false Entities[4].Code: 504 Entities[4].FullName: Specific circumstances indicator Entities[4].Description: Specific circumstances indicator Entities[4].IsDeleted: false Entities[5].Code: 131 Entities[5].FullName: Gross mass Entities[5].Description: Gross mass Entities[5].IsDeleted: false Entities[6].Code: 146 Entities[6].FullName: Total packages Entities[6].Description: Total packages Entities[6].IsDeleted: false Entities[7].Code: 61B Entities[7].FullName: Authentication Entities[7].Description: Authentication Entities[7].Entities[0].Code: 104 Entities[7].Entities[0].FullName: Signature/Authentication Entities[7].Entities[0].Description: Signature/Authentication Entities[7].Entities[0].IsDeleted: false Entities[7].IsDeleted: false Entities[8].Code: 02A Entities[8].FullName: Deferred Payment Entities[8].Description: Deferred Payment Entities[8].Entities[0].Code: D031 Entities[8].Entities[0].FullName: Deferment category code Entities[8].Entities[0].Description: Category code Entities[8].Entities[0].IsDeleted: false Entities[8].Entities[1].Code: D005 Entities[8].Entities[1].FullName: Deferment ID Entities[8].Entities[1].Description: ID Entities[8].Entities[1].IsDeleted: false Entities[8].Entities[2].Code: D006 Entities[8].Entities[2].FullName: Deferment Type Entities[8].Entities[2].Description: Type Entities[8].Entities[2].IsDeleted: false Entities[8].IsDeleted: false Entities[9].Code: 03A Entities[9].FullName: Additional Information Entities[9].Description: Additional Information Entities[9].Entities[0].Code: 226 Entities[9].Entities[0].FullName: Additional Information Statement code Entities[9].Entities[0].Description: Statement code Entities[9].Entities[0].IsDeleted: false ....
我在
我在Startup.cs中使用了以下代码来更改限制,问题已经解决,现在可以成功绑定
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
});