Я изначально разместил эту проблему на GitHub здесь: https://github.com/aspnet/Mvc/issues/8723
Здесь есть репозиторий GitHub с репродукцией проблемы:
https://github.com/Costo/aspnetcore-binding-bug
Я использую ASP.NET Core 2.2 Preview 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; }
}
Пользовательская модель переплета (намеренно упрощена, чтобы не делать ничего особенного):
public class NumberModelBinder : IModelBinder
{
private readonly NumberStyles _supportedStyles = NumberStyles.Float | NumberStyles.AllowThousands;
private DecimalModelBinder _innerBinder;
public NumberModelBinder(ILoggerFactory loggerFactory)
{
_innerBinder = new DecimalModelBinder(_supportedStyles, loggerFactory);
}
/// <inheritdoc />
public Task BindModelAsync(ModelBindingContext bindingContext)
{
return _innerBinder.BindModelAsync(bindingContext);
}
}
Контроллер:
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();
}
}
Razor view:
@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>