Ошибка привязки в пользовательской модели minder удаляет значение, введенное пользователем.

Я использую ASP.NET MVC 3 RTM, и у меня есть такая модель представления:

public class TaskModel
{
  // Lot's of normal properties like int, string, datetime etc.
  public TimeOfDay TimeOfDay { get; set; }
}

Свойство TimeOfDay - это моя настраиваемая структура, которая довольно проста, поэтому я не включаю ее здесь. Я создал привязку пользовательской модели для привязки этой структуры. Папка модели довольно проста:

public class TimeOfDayModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        try
        {
            // Let the TimeOfDay struct take care of the conversion from string.
            return new TimeOfDay(result.AttemptedValue, result.Culture);
        }
        catch (ArgumentException)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Value is invalid. Examples of valid values: 6:30, 16:00");
            return bindingContext.Model; // Also tried: return null, return value.AttemptedValue
        }
    }
}

Моя настраиваемая привязка модели работает нормально, но проблема в том, что значение, указанное пользователем, не может быть преобразовано или проанализировано. Когда это происходит (когда конструктор TimeOfDay выдает ArgumentException), я добавляю ошибку модели, которая правильно отображается в представлении, но введенное пользователем значение, которое не может быть преобразовано, теряется. Текстовое поле, в которое пользователь ввел значение, просто пусто, а в источнике HTML для атрибута значения установлена ​​пустая строка: "".

РЕДАКТИРОВАТЬ: Мне интересно, может ли это быть мой шаблон редактора, который делает что-то не так, поэтому я включаю его здесь:

@model Nullable<TimeOfDay>
@if (Model.HasValue)
{
    @Html.TextBox(string.Empty, Model.Value.ToString());
}
else
{
    @Html.TextBox(string.Empty);
}

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


person René    schedule 03.04.2011    source источник


Ответы (1)


Ага! Я наконец нашел ответ! Этот блог пост дал ответ. Чего мне не хватало, так это вызова ModelState.SetModelValue() в папке с моей моделью. Итак, код будет таким:

public class TimeOfDayModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        try
        {
            // Let the TimeOfDay struct take care of the conversion from string.
            return new TimeOfDay(result.AttemptedValue, result.Culture);
        }
        catch (ArgumentException)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Value is invalid. Examples of valid values: 6:30, 16:00");
            // This line is what makes the difference:
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, result);
            return bindingContext.Model;
        }
    }
}

Я надеюсь, что это спасет кого-то еще от часов разочарования, которые я пережил.

person René    schedule 04.04.2011