Asp.net core mvc 使用[ModelBinder]属性时,在模型绑定期间执行有限循环

Asp.net core mvc 使用[ModelBinder]属性时,在模型绑定期间执行有限循环,asp.net-core-mvc,Asp.net Core Mvc,我最初将此问题发布到GitHub的以下位置: 这里有一个GitHub存储库,其中包含问题的再现: 我正在使用ASP.NETCore2.2预览版3 当对“子”模型数组的属性使用自定义模型绑定器(带有[ModelBinder]属性)时,请求的模型绑定阶段进入无限循环。请参见此屏幕截图: 如果在顶级模型属性上使用自定义模型绑定器,则该绑定器工作得很好,但我想了解为什么在一系列子模型中使用时它不工作。在此方面的任何帮助都将不胜感激 谢谢大家! 以下是模型、控制器、视图和自定义活页夹的代码: 模型:

我最初将此问题发布到GitHub的以下位置:

这里有一个GitHub存储库,其中包含问题的再现:

我正在使用ASP.NETCore2.2预览版3

当对“子”模型数组的属性使用自定义模型绑定器(带有[ModelBinder]属性)时,请求的模型绑定阶段进入无限循环。请参见此屏幕截图:

如果在顶级模型属性上使用自定义模型绑定器,则该绑定器工作得很好,但我想了解为什么在一系列子模型中使用时它不工作。在此方面的任何帮助都将不胜感激

谢谢大家!


以下是模型、控制器、视图和自定义活页夹的代码:

模型:

public class TestModel
{
    public TestInnerModel[] InnerModels { get; set; } = new TestInnerModel[0];

    [ModelBinder(BinderType = typeof(NumberModelBinder))]
    public decimal TopLevelRate { get; set; }
}

public class TestInnerModel
{
    public TestInnerModel()
    {
    }

    [ModelBinder(BinderType = typeof(NumberModelBinder))]
    public decimal Rate { get; set; }
}
自定义模型活页夹(有意简化为不做任何特殊操作):

Razor视图:

@model TestModel;

<form asp-controller="Home" asp-action="Index" method="post" role="form">
    <div>
        <input asp-for="@Model.TopLevelRate" type="number" min="0" step=".01" />

    </div>
    <div>
        @for (var i = 0; i < Model.InnerModels.Length; i++)
        {
            <input asp-for="@Model.InnerModels[i].Rate" type="number" min="0" step=".01" />
        }
    </div>

    <input type="submit" value="Go" />
</form>
@model TestModel;
@对于(var i=0;i
A已发布到GitHub发行版:

@Costo问题是您没有通知模型绑定系统绑定器使用了值提供者。
ComplexTypeModelBinder
始终认为数据可用于下一个
TestInnerModel
实例,而最外层的绑定器(
CollectionModelBinder
)一直在运行。为了解决这个问题

换句话说,在这种情况下,
BindingSource.Custom
default
[ModelBinder]
使用的是不正确的。幸运的是,容器中POCO类型属性的自定义模型绑定应该是其中极少数的一种

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View(new TestModel
        {
            TopLevelRate = 20m,
            InnerModels = new TestInnerModel[]
            {
                new TestInnerModel { Rate = 2.0m },
                new TestInnerModel { Rate = 0.2m }
            }
        });
    }

    [HttpPost]
    public IActionResult Index(TestModel model)
    {
        return Ok();
    }
}
@model TestModel;

<form asp-controller="Home" asp-action="Index" method="post" role="form">
    <div>
        <input asp-for="@Model.TopLevelRate" type="number" min="0" step=".01" />

    </div>
    <div>
        @for (var i = 0; i < Model.InnerModels.Length; i++)
        {
            <input asp-for="@Model.InnerModels[i].Rate" type="number" min="0" step=".01" />
        }
    </div>

    <input type="submit" value="Go" />
</form>
[MyModelBinder]
public decimal Rate { get; set; }

private class MyModelBinderAttribute : ModelBinderAttribute
{
    public MyModelBinderAttribute()
        : base(typeof(NumberModelBinder))
    {
        BindingSource = BindingSource.Form;
    }
}