1

I have a model with enum property which based on 'int'. I need to validate that this property is not empty. But NotEmpty forbids 0 value. And NotNull just doesn't work because enum property cannot be null. I cannot make my property nullable. How can I do such validation?

John Zabroski
  • 2,212
  • 2
  • 28
  • 54
ilyabreev
  • 628
  • 6
  • 20

2 Answers2

2

As long as the enum type is int you can do the following:

public class Status
    {
        public StatusType type { get; set; }
    }

    public enum StatusType
    {
        open = 1,
        closed = 2
    }

    public class StatusValidator : AbstractValidator<Status>
    {
        public StatusValidator()
        {
            RuleFor(x => x.type).Must(x => x != 0);
        }

    }

If you can't avoid 0 you can define a workaround for the model as follow (source: Choosing the default value of an Enum type without having to change values):

[Note: you need to include using System.ComponentModel;]

public class Status
{
    public StatusType type { get; set; }
}

[DefaultValue(_default)]
public enum StatusType
{
    _default = -1,
    test = 0,
    open = 1,
    closed = 2,

}

public static class Utilities
{
    public static TEnum GetDefaultValue<TEnum>() where TEnum : struct
    {
        Type t = typeof(TEnum);
        DefaultValueAttribute[] attributes = (DefaultValueAttribute[])t.GetCustomAttributes(typeof(DefaultValueAttribute), false);
        if (attributes != null &&
            attributes.Length > 0)
        {
            return (TEnum)attributes[0].Value;
        }
        else
        {
            return default(TEnum);
        }
    }
}

public class StatusValidator : AbstractValidator<Status>
{
    public StatusValidator()
    {
        RuleFor(x => x.type).Must(x => x != Utilities.GetDefaultValue<StatusType>());
    }

}
Community
  • 1
  • 1
Giovanni Romio
  • 1,008
  • 1
  • 11
  • 30
  • Sorry but I can't. Can't avoid `0` value in my enum. – ilyabreev Apr 26 '17 at 16:51
  • Thank you, Giovanni! Your suggestion is good. But I'd like to keep my enum clean and not introduce some default value. Instead, in constructor of my model I set property to some invalid value (-1 for example) and cast it to enum. Then `IsInEnum` method works like a charm! – ilyabreev Apr 26 '17 at 20:01
-1

I suppose you want to validate the model in a mvc controller but you should be more clear about your utilization context. I think the model should be as wide as possible in terms of types to fit any possible choice the user make at UI level, for example always using nullable types. When the model binding try to build the object it match property names to request keys/values and set the matching value into the property. When it dosen't find any match in the request it leaves the property to its default value(0 in case of int). In that case the only way you have to know if the user left the field empty or intentionally wrote a zero value in it is to check the model state. Well in the first case an error (field can not be null...etc etc) will be tracked in the model state and checking the model state you can be aware if the user set the value or not. Fluent validation comes into play after the model binding and it relies on the work of model binder itselfe and poor him can't really understand what zero really mean (empty/missing value or zero value).

Ghini Antonio
  • 2,992
  • 2
  • 25
  • 48