2009-02-25 4 views
2

Ich habe ein benutzerdefiniertes Objekt namens S2kBool, das in und von einem regulären Boolean-Objekt konvertiert werden kann. Im Grunde erlaubt es meiner Anwendung, boolesche Werte in meiner alten Datenbank so zu behandeln, wie sie C# -Booleans behandelt. Wenn ich versuche, ein Kontrollkästchen zu verwenden, um den Wert einer S2kBool-Eigenschaft festzulegen, schlägt das Problem fehl.UpdateModel wird einen booleschen Wert nicht korrekt konvertieren

-Code funktioniert wie folgt:

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

MyClassInstance.MyProperty = true; 

Aber es ist fast wie Update einen tatsächlichen Bool Typen erwartet, eher als ein Objekt, das zu einem bool umgewandelt werden kann. Ich kann es jedoch nicht wirklich sagen, da die ausgelöste Ausnahme so vage ist:

Das Modell wurde nicht erfolgreich aktualisiert.

Wie kann ich das umgehen? Benötige ich einen benutzerdefinierten ModelBinder?

Danke!

Antwort

2

Während Charlinos Lösung clever ist und funktionieren wird, würde ich persönlich die Idee nicht mögen, meine Domain-Entitäten mit einer zusätzlichen Eigenschaft nur für diesen Zweck zu "beschmutzen". Ich denke du hattest die Antwort schon oben: ein Custom Modelbinder. Etwas wie:

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

Und dann können Sie Ihre Controller-Aktion ändern aussehen:

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

Wenn Sie ein bisschen mehr Arbeit in die Modelbinder setzen Sie es mit dem Bindemittel global arbeiten koennten registriert - aber die Implementierung, die ich Ihnen oben gegeben habe, sollte für Cherry-Picking-Werte bei Bedarf funktionieren.

+0

Angenommen, Sie möchten niemals eine Eigenschaft des Typs S2kBool mit einem anderen Modellbinder binden, würde ich den benutzerdefinierten Binder der Auflistung im Anwendungsstartereignis global.asax für diesen Typ hinzufügen, anstatt die Bindungsattribute in der Aktion zu verwenden selbst. –

+0

Wird das benutzerdefinierte Modellbinder in global.asax hinzugefügt, wird es automatisch auf alle S2kBool-Eigenschaften angewendet? In dem Code, den ich oben angegeben habe, würde mein Modellbinder dann auf MyClass.MyProperty angewendet oder funktioniert es nur bei Methodenargumenten, wenn ich versuchte, Daten an MyClass zu binden? –

2

Sie könnten eine zusätzliche Bool-Eigenschaft vom Typ bool haben, die bei Änderung den Wert Ihrer S2kBool-Eigenschaft ändert.

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

Sie dann nur noch die MyPropertyBool in Ihrem HTML-Formular und die Modelbinder werden über seine Art nicht ausflippen.

Ich verwende diese Technik für Eigenschaften wie Passwort & HashedPassword wo Passwort Eigentum von dem HTML-Formular ist, dass der Modelbinder zu und in der Setter Password bindet es setzt HashedPassword an den Hash davon, die dann in der Datenbank beibehalten wird oder was je.

Verwandte Themen