2010-04-06 14 views
5

Używam obiektu, który pasuje do wszystkich pól w moim formularzu. Następnie używam domyślnego powiązania, aby zapełnić obiekt w moim działaniu, tak jak to;Problem danych formularza wiążącego MVC

public ActionResult GetDivisionData(DivisionObj FormData) 

My DivisionObj inicjuje wszystkich jego wartości string.empty w konstruktorze.

Problem polega na tym, że gdy spinacz wypełnia model z przesłanych danych formularzy, wszelkie dane, które nie zostały wysłane, są ustawione na wartość null w obiekcie, mimo że zainicjowałem obiekt, aby zawierał puste ciągi.

Czy można to zmienić, aby niewysłane dane były pustym ciągiem znaków.

+0

Musisz ustawić właściwości pustych ciągów w akcjach sterownika, obsługiwać je w logice biznesowej lub warstwie dostępu do danych. Sugerowałbym, że była to funkcja dla twojego BL. – Lazarus

Odpowiedz

13

Jest to domyślne zachowanie DefaultModelBinder, a dokładniej framework DataAnnotations. ConvertEmptyStringToNull jest domyślnie ustawiony na true. Można utworzyć własny segregator modelu i zastąpić domyślny segregator modelu.

public class EmptyStringModelBaseBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     bindingContext.ModelMetadata.ConvertEmptyStringToNull = false; 

     return base.BindModel(controllerContext, bindingContext); 
    } 
} 

Następnie w globalnym ...

ModelBinders.Binders.DefaultBinder = new EmptyStringModelBaseBinder(); 

Chociaż ja żeby mieli statycznego sposobu ustawiania tej domyślnej modelbinder. Może w wersji v3 :)

Można również użyć atrybutu [DisplayFormat(ConvertEmptyStringToNull=false)], aby ustawić to na podstawie właściwości.

2

Zawsze można użyć [Bind(Exclude="PropertyName1,PropertyName2,PropertyName3")] wykluczyć pewne właściwości wiążące od:

public ActionResult GetDivisionData([Bind(Exclude="PropertyName1,PropertyName2,PropertyName3")]DivisionObj FormData) 

Jeśli naprawdę mieć String.Empty właściwości ciąg, można użyć tego spoiwa:

public class EmptyStringModelBinder : DefaultModelBinder 
{ 
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor) 
    { 
     base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
     if (propertyDescriptor.PropertyType == typeof(String)) 
      propertyDescriptor.SetValue(bindingContext.Model,propertyDescriptor.GetValue(bindingContext.Model) ?? String.Empty); 
    } 
} 

You Będziesz musiał również uruchomić to na stronie global.asax:

ModelBinders.Binders.DefaultBinder = new EmptyStringModelBinder(); 
+0

To jest bardziej dynamiczne. Mój użytkownik mógł wypełnić formularz nieprawidłowo. Chodzi o to, że mój obiekt musi zawierać string.empty, jeśli pole pozostało puste. – John

1

Mogę tylko confi rm, że widzę takie same wyniki jak ty. Dostępne opcje:

Jednym ze sposobów jest wykluczenie właściwości, jak wyjaśnił LukLed. Ale to doprowadzi do powielenia kodu i będziesz musiał to zrobić na każdej akcji kontrolera za każdym razem, gdy DivisionObj (lub jakakolwiek inna klasa Modelu, którą chcesz udekorować) pojawi się jako parametr działania. Soo to trochę uciążliwe ...

Obecnie jestem w trakcie wielu problemów z różnymi niestandardowymi właściwościami, niektóre z nich muszą być tworzone w contructors, niektóre z nich wymagają wartości tylko w środowisku uruchomieniowym i innych, które są również specjalne w pewnym sensie.

Stwierdziłem, że dla mnie najlepiej jest iść z Custom Model Binder i robić większość tych rzeczy.

+0

Mówisz więc, że domyślny segregator modelowy sprawi, że wartość obiektu będzie równa zero, jeśli nie znaleziono zgodnej wartości w danych posta, nawet jeśli obiekt został zainicjowany na ciąg znaków string.empty? – John

+0

Wypróbowałem to, ponieważ miałem trochę kodu pod ręką, gdy odpowiadałem na twoje pytanie i działało tak, jak go doświadczasz. Ale nie jestem w 100% pewien, czy to zawsze działa w ten sposób. Możesz pobrać źródło ASP.NET MVC samodzielnie i sprawdzić implementacje DefaultValueProvider i DefaultModelBinder i przekonać się, jak to zrobić. – mare

Powiązane problemy