UpdateModel не будет правильно преобразовывать логическое значение

2

У меня есть пользовательский объект S2kBool, который может быть преобразован в и из обычного булева объекта. В принципе, это позволяет моему приложению обрабатывать логические значения в моей старой базе данных так же, как это относится к С# booleans. Тогда проблема заключается в том, что когда я пытаюсь использовать флажок для установки значения свойства S2kBool, он терпит неудачу.

Код, подобный этому, работает:

public class MyClass {
    public S2kBool MyProperty { get; set; }
}

MyClassInstance.MyProperty = true;

Но он почти как UpdateModel ожидает фактического типа bool, а не объекта, который можно преобразовать в bool. Однако я не могу сказать, так как исключенное брошенное расплывчато:

Модель не была успешно обновлена.

Как я могу обойти это? Мне нужен пользовательский ModelBinder?

Спасибо!

Теги:
asp.net-mvc

2 ответа

2
Лучший ответ

Хотя решение Charlino умное и будет работать, мне лично не понравилась бы идея "загрязнять" мои объекты домена дополнительным свойством только для этой цели. Думаю, у вас уже был ответ вверх: пользовательский модельный блок. Что-то вроде:

public class S2kBoolAttribute : CustomModelBinderAttribute, IModelBinder
{
    public override IModelBinder GetBinder()
    {
        return this;
    }

    public object BindModel( ControllerContext controllerContext, ModelBindingContext bindingContext )
    {
        ValueProviderResult result;
        return bindingContext.ValueProvider.TryGetValue( bindingContext.ModelName, out result )
            ? (S2kBool)result.ConvertTo( typeof( bool ) )
            : null;
    }
}

И затем вы можете изменить действие контроллера следующим образом:

public ActionResult Foo( [S2kBool]S2kBool myProperty ){
    myClassInstance.MyProperty = myProperty;
    SaveToLegacyDb(myClassInstance);
    return RedirectToAction("Bar");
}

Если вы добавите немного больше работы в модельный блок, вы можете заставить его работать со связующим, зарегистрированным в глобальном масштабе, - но реализация, которую я вам дал выше, должна работать для получения значений вишневого цвета при необходимости.

  • 0
    Предполагая, что вы никогда не захотите связывать свойство типа S2kBool с любым другим связывателем модели, я бы добавил настраиваемое связывание в коллекцию в событии запуска приложения global.asax для этого типа, вместо того чтобы использовать атрибуты привязки в самом действии.
  • 0
    Добавив пользовательский связыватель модели в global.asax, будет ли он автоматически применяться ко всем свойствам S2kBool? Например, в приведенном выше коде, если я пытаюсь привязать данные к MyClass, будет ли привязка моей модели применяться к MyClass.MyProperty или он будет работать только с аргументами метода?
2

У вас может быть дополнительное свойство bool типа bool, которое при изменении изменит значение вашего свойства S2kBool.

public class MyClass {
    public S2kBool MyProperty { get; set; }
    public bool MyPropertyBool {
        get
        {
            return (bool)MyProperty;
        }
        set
        {
            MyProperty = value;
        }
    }
}

Тогда у вас будет только MyPropertyBool в вашей форме html, и модельный блок не будет волноваться об этом типе.

Я использую этот метод для таких свойств, как Password и HashedPassword, где Password является свойством из html-формы, с которой привязан ModelBinder, и в настройщике пароля он устанавливает HashedPassword на хэш, который затем сохраняется в базе данных или когда-либо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню