Установка значений ModelState в пользовательском связывателе модели - PullRequest
15 голосов
/ 07 апреля 2010

Я использую привязку пользовательской модели в 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 не обновляется. Я знаю это, потому что у меня есть свойство Required для свойства Slug моего бизнес-объекта, и, хотя я изменил ModelStateDictionary в моем пользовательском связывателе модели, предоставив ему Slug (как вы можете видеть выше), ModelState.IsValid по-прежнему имеет значение false.

Если я поместил ModelState ["Slug"] в окно наблюдения в сеансе отладки, он скажет, что в нем есть ошибки (1), поэтому, очевидно, он пуст и как таковой завершается неудачей.

Как правильно изменить ModelState внутри пользовательского кода связывания модели?

1 Ответ

20 голосов
/ 07 апреля 2010

По-видимому, нет способа повторно проверить 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));
...