提问人:bvsta 提问时间:11/5/2023 更新时间:11/5/2023 访问量:43
如何将字段值作为列表传递到模型绑定
how do i pass field values to my model binding as a list
问:
我正在使用以下脚本在表单中的卡片中动态添加和删除字段。我正在尝试将值传递给我的模型绑定属性,该属性是一个List<ushort>
<div style="width:40%;">
<div class="">
<div class="col-lg-12">
<div id="row">
<div class="input-group m-3">
<div class="input-group-prepend">
<button class="btn btn-danger"
id="DeleteRow"
type="button">
<i class="bi bi-trash"></i>
Delete
</button>
</div>
<input type="text" class="form-control m-input">
</div>
</div>
<div id="newinput"></div>
<button id="rowAdder" type="button" class="btn btn-dark">
<span class="bi bi-plus-square-dotted">
</span> ADD
</button>
</div>
</div>
</div>
<script type="text/javascript">
$("#rowAdder").click(function () {
newRowAdd =
'<div id="row"> <div class="input-group m-3">' +
'<div class="input-group-prepend">' +
'<button class="btn btn-danger" id="DeleteRow" type="button">' +
'<i class="bi bi-trash"></i> Delete</button> </div>' +
'<input type="text" class="form-control m-input"> </div> </div>';
$('#newinput').append(newRowAdd);
});
$("body").on("click", "#DeleteRow", function () {
$(this).parents("#row").remove();
})
</script>
我尝试使用绑定到模型属性的隐藏字段,并在提交到数组时更新该字段。
function updatePortsInput() {
console.log("updatePortsInput called");
var ports = [];
$(".m-input").each(function () {
var portValue = parseInt($(this).val());
if (!isNaN(portValue) && portValue >= 0 && portValue <= 65535) {
ports.push(portValue);
}
});
$('[name="Ports"]').val(JSON.stringify(ports));
}
<input type="hidden" id="portsInput" name="Ports" asp-for="Ports" />
但是我无法使用生成的字段的值填充我的列表。
有人对此有想法吗?
答:
您在请求中混合了表单和 json 内容。您没有显示您发送请求的确切方式,但看起来您正在提交表单。默认情况下,这将发送 类型的内容,因此请求正文将如下所示(格式化):application/x-www-form-urlencoded
ports: "[1,2,3,4,5,6,7]"
__RequestVerificationToken: "CfDJ8KVrOUsD…"
框架现在会将处理程序参数与请求中的值(字符串)进行匹配。它不知道字符串是json数组,所以会无法解析成指定的类型。ports
List<ushort>
你必须决定:
- 继续发送混合内容并在后端手动解析 Json
- 发送表单请求正文
- 发送 Json 请求正文
选项 1:自行解析 Json
保持一切原样,但在页面处理程序上,更改为 然后调用它。List<ushort> ports
string ports
JsonSerializer.Deserialize<List<ushort>>(ports)
如果您有其他输入要与相同的请求一起发送,并且您希望框架以通常的方式处理它们,这可能会很有趣。但实际上,我更喜欢选项 2。
选项 2:发送表单内容
给你所有的输入命名,删除Json的东西,提交表格,它就可以工作了。ports
<form asp-page-handler="Form" method="POST">
<input name="ports" type="number" value="1"/>
<input name="ports" type="number" value="2"/>
<input name="ports" type="number" value="3"/>
<button type="submit">Submit</button>
</form>
public IActionResult OnPostForm(List<ushort> ports)
{
foreach (var port in ports)
Console.WriteLine(port);
return RedirectToPage();
}
就做这个。
选项 3:发送 Json 内容
不要将 Json 数组放在隐藏的表单输入中。相反,将其放入请求正文中,并将请求内容类型声明为 .告诉页面处理程序从请求正文中获取参数。框架将神奇地为您解析 json:application/json
<form asp-page-handler="Json" onsubmit="go(event)">
<input class=".m-input" type="number" value="1" />
<input class=".m-input" type="number" value="2" />
<input class=".m-input" type="number" value="3" />
<button type="submit">Submit</button>
</form>
<script>
$(".m-input").each(function () {
var portValue = parseInt($(this).val());
if (!isNaN(portValue) && portValue >= 0 && portValue <= 65535) {
ports.push(portValue);
}
});
//above is the code that collects your inputs into an array,
//which i copied from you.
//below is a vanilla javascript fetch request that sends this
//array as json. You can probably do that with jQuery, too,
//but I don’t know how.
async function go(e) {
e.preventDefault();
fetch('@Url.Page("", "Json")', {
method: 'POST',
headers: new Headers({ 'content-type': 'application/json' }),
body: JSON.stringify(ports),
});
}
</script>
public IActionResult OnPostJson([FromBody] List<ushort> ports)
{
foreach (var port in ports)
Console.WriteLine(port);
return new JsonResult("thx i enjoyed those ports");
}
与其他选项相比,这将发送异步请求,即浏览器不会导航。
因为你是用javascript自己构建请求的,所以 ASP.NET Core可能随表单生成的CSRF令牌不会自动发送,所以你需要弄清楚这一点(你可以在标头中发送它,或者让你的后端忽略它)。
评论