Повторное заполнение формы ASP.NET MVC

У меня есть контроллер с двумя действиями:

[AcceptVerbs("GET")]
    public ActionResult Add()
    {
        PrepareViewDataForAddAction();
        return View();
    }


[AcceptVerbs("POST")]
    public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
    {
        if (ViewData.ModelState.IsValid)
        {
            GigManager.Save(gig);
            return RedirectToAction("Index", gig.ID);
        }
        PrepareViewDataForAddAction();
        return View(gig);
    }

Как видите, когда форма публикует свои данные, действие «Добавить» использует GigBinder (реализация IModelBinder).

В этом переплете у меня есть:

 if (int.TryParse(bindingContext.HttpContext.Request.Form["StartDate.Hour"], out hour))
        {
           gig.StartDate.Hour = hour;
        }
        else
        {
            bindingContext.ModelState.AddModelError("Doors", "You need to tell us when the doors open");
        }

Форма содержит текстовое поле с идентификатором "StartDate.Hour".

Как вы можете видеть выше, GigBinder проверяет, что пользователь ввел целое число в текстовое поле с идентификатором «StartDate.Hour». Если нет, ошибка модели добавляется в состояние модели с помощью AddModelError.

Поскольку свойство gigs gigs.StartDate.Hour строго типизировано, я не могу установить для него значение, например, «TEST», если пользователь ввел это в текстовое поле формы.

Следовательно, я не могу установить значение gigs.StartDate.Hour, поскольку пользователь ввел строку, а не целое число.

Поскольку действие «Добавить» возвращает представление и передает модель (return View(gig);), если состояние модели недопустимо, когда форма повторно отображается с сообщениями проверки, значение «ТЕСТ» не отображается в текстовом поле. Вместо этого будет значение по умолчанию gig.StartDate.Hour.

Как мне обойти эту проблему? Я действительно застрял!


person iasksillyquestions    schedule 04.01.2009    source источник


Ответы (3)


Я думаю, проблема в том, что ваша ViewModel недостаточно точно соответствует вашему представлению. В MVC очень важно, чтобы ваша ViewModel максимально точно соответствовала вашему View.

В вашей ViewModel вы принимаете целое число, но в своем представлении вы используете TextBox для отображения свойства, что позволяет использовать любой тип текста. Здесь есть несоответствие, и трудности, с которыми вы сталкиваетесь, пытаясь их отобразить, являются симптомом несоответствия.

Я думаю, вам следует:
1. Изменить тип свойства ViewModel на строку, а затем выполнить проверку в контроллере, чтобы убедиться, что введенная строка действительно является числом, или:
2. Изменить элемент управления, отображаемый представлением. к элементу управления, который позволит вводить число только с помощью пользовательского элемента управления или проверки Javascript (как рекомендует @Qun Wang)

Лично я бы рекомендовал вариант 1. Таким образом, ViewModel не зависит от реализации View.

person Mac    schedule 29.04.2010

Не могли бы вы сделать это в своем методе PrepareViewDataForAddAction?..

if (!ViewData.ModelState.IsValid)
    {
        ViewData["StartDate.Hour"] = "Error";
    }

Другие поля в форме по-прежнему будут заполняться в зависимости от свойств объекта Gig.

person Dominic Betts    schedule 06.01.2009

Я думаю, вам нужно сначала выполнить базовую проверку на стороне клиента. не позволяйте ему размещать сообщения на сервере.

person Qun Wang    schedule 10.04.2010