Dan
Dan

Reputation: 3268

IValidatableObject and Nullable value types

I have a struct that implements IValidatableObject, which I use for properties on a view model. The validation works fine with non-nullable properties, but if add a property of type Nullable<MyStruct> the IValidatableObject.Validate method is never called for that property, even if it has a value.

Is there any way that I trigger the validation on my nullable properties too, or is IValidatableObject not intended to be used with value types?

Thanks


Additional information:

I wanted to be able to specify units when entering data in my form, e.g. 10m, 100km, 1cm etc. I also wanted to validate that the entered data was within range and of a correct format. My struct converts the string with potentially different units (100cm/100m/1km) into a decimal property which always has the same unit (1/100/1000) and vice-versa.

I used IValidatableObject for validation because the validation will always be the same for any instance of MyStruct - I didn't want to add an attribute each time it is used.

My model would look something like this:

public class MyModel 
{
    public MyStruct Ab {get; set;}
    public MyStruct? Cd {get; set;}
}

My view is a strongly typed view using the model, which renders my struct as a text box using a display template. When the form is posted, I have a custom model binder to convert the entered string back to my struct.

My controller action looks like:

public ActionResult MyAction(MyModel model)
{
    //do stuff
}

The model is bound ok for properties of type MyStruct and Nullable<MyStruct>.

Upvotes: 2

Views: 602

Answers (1)

Dan
Dan

Reputation: 3268

It seems that this is not possible.

I dug into the MVC source. In System.Web.Mvc.DataAnnotationsModelValidatorProvider there is the following code:

// Produce a validator if the type supports IValidatableObject
if (typeof(IValidatableObject).IsAssignableFrom(metadata.ModelType)) {
    //stuff
}

According to this rejected bug report, Nullable<T> cannot be assigned to an interface that T implements:

"In short, a "DateTime?" value can be unboxed to a DateTime or an IFormattable value. But it cannot be assigned to a DateTime or IFormattable location."

Thus no validators are returned.

Looks like I will have to do this another way.

Upvotes: 2

Related Questions