Установка значений ModelState в привязке настраиваемой модели
Я использую настраиваемое связующее устройство в ASP.NET MVC 2, которое выглядит так:
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
BaseContentObject obj = (BaseContentObject)base.BindModel(controllerContext, bindingContext);
if(string.IsNullOrWhiteSpace(obj.Slug))
{
// creating new object
obj.Created = obj.Modified = DateTime.Now;
obj.ModifiedBy = obj.CreatedBy = controllerContext.HttpContext.User.Identity.Name;
// slug is not provided thru UI, derivate it from Title; property setter removes chars that are not allowed
obj.Slug = obj.Title;
ModelStateDictionary modelStateDictionary = bindingContext.ModelState;
modelStateDictionary.SetModelValue("Slug", new ValueProviderResult(obj.Slug, obj.Slug, null));
...
Когда я вернусь из этого связующего в действие контроллера, мой бизнес-объект, который предоставляется как параметр для действия, правильно изменен (строки obj.Created =.... work).
Однако ModelState не обновляется. Я знаю это, потому что я обязателен для своего свойства Slug бизнес-объекта, и хотя я изменил ModelStateDictionary в моем настраиваемом соединителе модели, предоставив ему Slug (как вы можете видеть выше), ModelState.IsValid все еще является ложным.
Если я поставлю ModelState [ "Slug" ] в окне "Watch" в сеансе Debug, он говорит, что он имеет ошибки (1), поэтому, по-видимому, он пуст и как таковой не работает.
Как я могу правильно изменить ModelState внутри кода привязки пользовательской модели?
Ответы
Ответ 1
По-видимому, нет способа переопределить ModelState после изменения значения некоторого ключа. IsValid остается ложным, потому что установка нового значения для некоторого ключа не вызывает повторной аттестации.
Решение состоит в том, чтобы сначала удалить ключ, который вызвал IsValid, чтобы быть ложным и воссоздать его и присвоить ему значение. Когда вы это сделаете, ModelState автоматически переоценивает и, если все в порядке, IsValid возвращает true.
Вот так:
bindingContext.ModelState.Remove("Slug");
bindingContext.ModelState.Add("Slug", new ModelState());
bindingContext.ModelState.SetModelValue("Slug", new ValueProviderResult(obj.Slug, obj.Slug, null));