Ошибка привязки в пользовательской модели minder удаляет значение, введенное пользователем - PullRequest
8 голосов
/ 04 апреля 2011

Я использую 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);
}

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

1 Ответ

17 голосов
/ 04 апреля 2011

Aha! Я наконец нашел ответ! Это сообщение в блоге дало ответ. Чего мне не хватало, так это позвонить 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;
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...