asp.net 如何将字段值作为列表传递给模型绑定

14ifxucb  于 11个月前  发布在  .NET
关注(0)|答案(1)|浏览(82)

我正在使用以下脚本动态地向表单中的卡片添加和删除字段。

<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" />


但我无法用生成的字段的值填充我的List。
有人对此有想法吗?

trnvg8h3

trnvg8h31#

你在请求中混合了form和json内容。你没有显示你到底是如何发送请求的,但看起来像是你在提交一个form。默认情况下,这将发送application/x-www-form-urlencoded类型的内容,所以请求体看起来像这样(格式化):

ports: "[1,2,3,4,5,6,7]"
__RequestVerificationToken: "CfDJ8KVrOUsD…"

字符串
框架现在将把你的处理程序参数ports匹配到请求中的值,这是一个字符串。它不知道这个字符串是一个json数组,所以它将无法将其解析为指定的类型List<ushort>
你必须决定:
1.继续发送混合内容,并在后台手动解析JSON
1.发送表单请求正文
1.发送JSON请求正文

选项一:自己解析Json

保持一切原样,但在页面处理程序中,将List<ushort> ports更改为string ports,然后在其上调用JsonSerializer.Deserialize<List<ushort>>(ports)
如果你有其他的输入要发送到同一个请求中,并且你希望框架以通常的方式处理它们,这可能会很有趣,但实际上,我更喜欢选项2。

选项二:发送表单内容

给予你所有的输入名称ports,删除JSON的东西,提交表单,它工作。

<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();
}

的数据

就做这一个

选项三:发送JSON内容

不要把你的JSON数组放在一个隐藏的表单输入中。相反,把它放在请求体中,并声明请求内容类型为application/json。告诉页面处理程序从请求体中获取参数。框架会神奇地为你解析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令牌不会自动发送,所以你需要弄清楚这一点(你可以在头中发送它,或者让你的后端忽略它)。

相关问题