UpdateModel не будет правильно преобразовывать логическое значение - PullRequest
2 голосов
/ 26 февраля 2009

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

Код работает следующим образом:

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

MyClassInstance.MyProperty = true;

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

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

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

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 февраля 2009

Хотя решение Чарлино является умным и будет работать, лично мне не хотелось бы, чтобы идея «испачкала» мои доменные сущности дополнительным свойством только для этой цели. Я думаю, что у вас уже есть ответ: пользовательское связующее. Что-то вроде:

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");
}

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

2 голосов
/ 26 февраля 2009

У вас может быть дополнительное свойство 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 в его хеш, который затем сохраняется в базе данных или в любом другом .

...