从 Razor 页面发布大型集合会导致错误 400

POSTing large collection from Razor page causes ERROR 400

当我 post 将大量对象(301 个对象)返回给页面处理程序时,我收到错误 400。

这是 form(为简单起见进行了删减):

        <form method="post" asp-page-handler="BuildJsonObject" asp-antiforgery="false">

            @{
                int i = 0;

                foreach (var node in Model.FlattenedNodes)
                {
                   <div class="form-inline mt-1">
                        <input type="hidden" name="FlattenedNodes[@i].Key" value="@node.Key" />
                        <input type="hidden" name="FlattenedNodes[@i].ValueKind" value="@node.ValueKind" />
                        <input type="hidden" name="FlattenedNodes[@i].Level" value="@node.Level" />
                        <input type="hidden" name="FlattenedNodes[@i].Key" value="@node.Key" />
                        <input type="hidden" name="FlattenedNodes[@i].ID" value="@node.ID" />
                        <input type="hidden" name="FlattenedNodes[@i].ParentId" value="@node.ParentID" />
                        <input type="text" class="form-control" name="FlattenedNodes[@i].StringValue" value="@node.StringValue" id="@id" />
                            
                    </div>
                    i++;
                }
                <button type="submit" class="btn btn-primary">Save</button>
            }
        </form>

我将 IgnoreAntiforgeryToken 属性应用于 PageModel,现在错误没有发生,但是 posted 集合是空的。

集合定义:

    [BindProperty]
    public List<TreeNode> FlattenedNodes { get; set; } = new List<TreeNode>();

我能够通过将此属性应用于页面模型来绕过此问题:

[RequestFormLimits(ValueCountLimit = x)]

我将 x 设置为 int.MaxValue,并且数据正常 posted,但我尝试使用更大的集合(~500 个条目),但出现此异常。

InvalidOperationException: Collection bound to 'FlattenedNodes' exceeded MvcOptions.MaxModelBindingCollectionSize (1024). This limit is a safeguard against incorrect model binders and models. Address issues in 'JsonDataTreeVisualizer.TreeNode'. For example, this type may have a property with a model binder that always succeeds. See the MvcOptions.MaxModelBindingCollectionSize documentation for more information.

为了禁用这个安全规则,我在 Startup.ConfigureServices 中添加了这个:

services.AddMvc(options =>
{
    options.MaxModelBindingCollectionSize = x;
});

我再次将 x 设置为 int.MaxValue。我还需要使用 IgnoreAntiforgeryToken:

[RequestFormLimits(ValueCountLimit = int.MaxValue)]
[IgnoreAntiforgeryToken]
public class IndexModel : PageModel
{
    .....
}

当然,制定这些安全规则是有充分理由的,如上面的异常消息中所解释的,例如,它可以防止攻击者可以 post 大数据包并导致带宽限制的拒绝服务攻击,但就我而言,我只是在一个业余项目中使用它。