0

I successfully made Enum binder and from what iv tested, everything works. But i want to have nullable enum parameter in my controller and when i change to nullable, my binder dont work.

 public class EnumBinder<T> : IModelBinder
    {
        private object DefaultValue { get; set; }
        public EnumBinder(object defaultValue)
        {
            DefaultValue = defaultValue;
        }


        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            if(result == null || string.IsNullOrEmpty(result.AttemptedValue))
            {
                return DefaultValue;
            }

            return GetEnumValue<T>(result.AttemptedValue);
        }



        public static object GetEnumValue<T>(string value)
        {
            var enums = Enum.GetValues(typeof (T)).Cast<T>().ToList();

            foreach (var e in enums)
            {
                var _enum = Enum.Parse(typeof (T), e.ToString());
                if (string.Equals(value, _enum.ToString(), StringComparison.InvariantCultureIgnoreCase))
                {
                    return _enum;
                }
            }

            return null;
        }

    }

Works on

 public virtual ActionResult ControllerName(Status status)
    {
       return View();
    }

but dont work on

 public virtual ActionResult ControllerName(Status? status)
    {
       return View();
    }

Of course i have registered my binder on application start

ModelBinders.Binders.Add(typeof(CallStatus), new EnumBinder<CallStatus>(null));

What i do wrong, why i cant return nullable enum in my controller?

tereško
  • 58,060
  • 25
  • 98
  • 150
Novkovski Stevo Bato
  • 1,013
  • 1
  • 23
  • 56

3 Answers3

2

CallStatus and CallStatus? are different types. The ? is syntactic sugar; CallStatus? is actually type System.Nullable<CallStatus>.

You need to either add another binder for typeof(Nullable<CallStatus>), or use a provider, as described here.

Community
  • 1
  • 1
Nick
  • 513
  • 3
  • 9
1

Model binding to Enums should just work with the default Model Binders in MVC 3 or 4, both plain and nullable.

Did you try with the default model binders and find that it wasn't working?

IIRC, the default binding behaviour depends on the value being the string representation of the enum value. This should be fine if you're using html views (like you seem to be). If you're using JSON or some other representation of your model you may get into trouble with the enum being converted to the integer representation on the way out, and if you need to be able to handle the integer value on the way back in then you may need a custom binder.

SimonF
  • 804
  • 1
  • 7
  • 14
0

You can set a Nullable type for your enum because it is a value type. Now in , if you want it as a optional parameter, you have to set a default value of you action, for sample:

public virtual ActionResult ControllerName(Status? status = null)
{
   if (status.HasValue) { /* some logic */ }
   return View();
}

Or using a default value for you enum parameter type

public virtual ActionResult ControllerName(Status status = Status.OK)
{
   /* some logic */
   return View();
}
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194