0
votes

I have two Dictionary<string, byte> properties in my model that should validate properly with from 0 to 5 items. For example the property skill (string dropDownListLabel, byte years).

Because I need to support non-javascript clients, I render all 5 input pairs to the browser, only binding existing dictionary items, and life is great. This gives 5 empty input pairs for a new plain HTML form, each with unique input names, which I also want.

Here's the serialization (input names) I use:

skill[0].Key = "", skill[0].Value = ""
 ... three more pairs ...
skill[4].Key = "", skill[4].Value = ""

But on POST, for Key/Value pairs with neither Key nor Value specified, DefaultModelBinder validation errors result on Value.

Is there a type and serialization I can use that will validate in DefaultModelBinder when both or neither Key and Value are POSTed, so MVC does as much work for me as possible, only adding pairs into a collection when they have content?

Thanks, Shannon

1
I followed Darin's second half of the accepted answer below. I pre-saturated a List<T> with null values, where T implements IValidatable to ensure both OR neither values are provided. Further I static methods on T to convert a List<T> to/from the corresponding IEnumerable<EntityObject>, as a convenient place to stash the saturation/dehydration process. Finally, I also placed the uniqueness comparison there and call it from IValidatable on the top-level model. This also solved a problem with MVC not using the configured DataAnnotationValidation "Value Required" message for Dictionary items.shannon

1 Answers

1
votes

You cannot bind an empty string to a value type (byte) so the default model binder marks your model as invalid. If you want to allow empty values you should use a nullable byte:

Dictionary<string, byte?>

UPDATE:

Another possibility is to use a collection of a custom type containing two properties each representing respectively the key and the value. Then use strongly typed helpers and editor templates in your view so that you don't have to worry about the wire format and finally you will need to ensure that the keys are unique so you will need a custom validator. Personally I use FluentValidation.NET for this part but if you are using data annotations you will need a custom attribute which will be used to decorate the collection property in the view model.