Я понимаю, что ModelBinder - это хорошее место для выполнения работы над запросом, так что вы держите этот тип кода вне контроллера. Работа со значениями формы будет примером. Это, кажется, имеет смысл, однако, я унаследовал приложение, которое использует Custom Binder, и я просто не могу понять, как и почему он работает.
Сам механизм связывания существует, чтобы иметь дело только с объектами TimeZoneInfo, поскольку они (часовые пояса) используются в приложении, поэтому он зарегистрирован в методе Application_Start в глобальном порядке, например:
binders.Add(new System.Collections.Generic.KeyValuePair<Type, IModelBinder>(typeof(TimeZoneInfo), new TimeZoneInfoModelBinder()));
Где связыватели имеют тип ModelBinderDictionary. Сам переплет выглядит так:
public class TimeZoneInfoModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
string tzId = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
try
{
return TimeZoneInfo.FindSystemTimeZoneById(tzId);
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
}
return null;
}
}
Теперь из-за пошагового выполнения кода, который я знаю, этот Binder вызывается только тогда, когда я отправляю данные обратно на сервер, который включает определенную модель, у которой есть свойство TimeZoneInfo. Мои предположения:
- Среда выполнения «знает» обо всех моделях и вызывает пользовательский связыватель, только когда находит свойство того же типа, что и тот, который был передан в связыватель.
- Причина, по которой это делается, заключается в том, что тип TimeZoneInfo является сложным типом и, следовательно, не может быть неявно преобразован в строку (данные POST)
Это правильное понимание данного конкретного случая или я что-то упустил?
Спасибо!