У меня есть, как мне кажется, несколько нормальная ситуация, когда мне нужно привязать посты формы к модели "заказа". Эта модель имеет несколько уровней информации:
Order.Billing.FirstName
Order.Billing.Address.City
Order.Billing.Address.Country
Используя DefaultModelBinder, если я отправлю форму в действие, которое принимает эту модель заказа в качестве параметра, следующие поля JustWork (TM):
<%=Html.TextBox("Billing.FirstName")%>
<%=Html.TextBox("Billing.Address.City")%>
Это поле не:
<%=Html.TextBox("Billing.Address.Country")%>
Морщина, которая у меня есть, принадлежит собственности страны. В нашем случае Address.Country возвращает экземпляр класса Country (логика ISO2 / 3 / Name / Code). Это не строка. Не удивительно, что по умолчанию это не работает.
Моей первой мыслью было создать CountryModelBinder (наследовать DefaultModelBinder) и ModelBinders.Binders. Добавить его к типу Country. Когда я это делаю, CountryModelBinder никогда не вызывается в описанном выше сценарии.
Моя вторая мысль состояла в том, чтобы создать AddressModelBinder (наследовать DefaultModelBinder) и связать его с нашим типом адреса. Хотя это вызывается, вызов SetProperty для «Country» имеет пустое значение, даже если в форме размещено поле с именем «Billing.Address.Country».
После некоторой обработки кажется, что поведение привязки модели вызывает CreateModel только тогда, когда модель является классом верхнего уровня, который требуется для действия, и для всех других связывателей их BindPropery / SetProperty вызывается для дочерних свойств.
Другими словами, если я создаю связующие модели для Order, OrderAddress (Billing), Address и Country. Для действия, которое принимает заказ, вызывается только OrderModelBinder.CreateModel. Для некоторых вещей вызываются ORderAddress и Address.BindProperty / SetProperty, и иногда аргумент значения SetProperty является пустым, если он явно размещен в имени, соответствующем другим сопоставлениям свойств поля.
Достаточно просто добавить код в OrderModelBinder, чтобы вытащить Billing.Address.Country из Request.Form. Но у меня есть несколько моделей, которые используют Address, и все они работают, что кажется сломанным.
Что мне здесь не хватает? Есть ли способ, чтобы CountryModelBinder действительно вызывался в этом случае? Я думаю, что CountryModelBinder должен вызываться, когда Billing.Address.Country сопоставлен со свойством Country подшивки Address.