2

I have a request to one of my actions in a controller that expects an enum as a key in the Querystring. I can see that the same is set in the QueryString but an exception is thrown by the server saying the same is not set and the error:

The parameters dictionary contains a null entry for parameter 'enumVar' of non-nullable type.

is thrown.

Here are the exception details:

Exception type: System.ArgumentException

Exception message: The parameters dictionary contains a null entry for parameter 'enumVar' of non-nullable type 'NameSpace.Enums.MyEnum' for method 'System.Web.Mvc.ActionResult GetContent(Int64, NameSpace.Enums.MyEnum, System.String, Int32, Int32, Int32, Int32, Int64)' in 'NameSpace.Controllers.MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

Parameter name: parameters

Request URL: http://myawesomeurl.local/app/My/GetContent?abc=a_123&xyz=434&enumVar=EnumValue&teamId=a_123&a=0&b=1&c=3&qwerty=123&token=234234231

Request path: app/My/GetContent

Let me know if you need more information. I am not sure how I should address the issue.

Update: My Enum defination:

public enum DisplayMode
{
    EnumValue,
    EnumValue1,
    EnumValue2
}

Also I should mention that the request fails only sometimes and not always and this is not consistent. This is an error that was logged in our exception db.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
user917670
  • 873
  • 1
  • 11
  • 22
  • 3
    Can you post your enum definition as well as your Action method for `GetContent()`? –  Dec 27 '11 at 14:16
  • I have added an update.. Let me know if you still need the defn of my action.FYI it isnt missing anything. – user917670 Dec 27 '11 at 14:21
  • Show your action method please (at least the parameters definition). Do you say, that you get sometimes an error and sometimes not when using the same query string? – Jan Dec 27 '11 at 15:04
  • @Jan that is correct! Weird huh! if it was consistent then I would hv figured out the issue or would hv debugged more.. :/ – user917670 Dec 28 '11 at 12:56
  • possible duplicate of [Model Binding to Enums in ASP.NET MVC 3](http://stackoverflow.com/questions/6051756/model-binding-to-enums-in-asp-net-mvc-3) – CatDadCode Jan 13 '14 at 21:53

2 Answers2

4

Pro Tip: don't name action method parameters action.

MVC puts the actual controller action method name in there, no matter what you've got in your querystring or your form (assuming you are using an {action} segment in your route). Route variables take precedence over everything, so if you happen to be trying to bind an Enum with a parameter name that's reserved, it simply ain't gonna wurk.

ErikE
  • 48,881
  • 23
  • 151
  • 196
  • 1
    Thank you!! I had no idea why the model binding wouldn't pick up the query string, and all because the parameter name was called action. This worked, and saved a ton of time. – firecape Jun 04 '16 at 22:42
1

It looks like the Default Model Binder is not dailed into enumerations. Your best bet would be to subclass the DefaultModelBinder class and handle the scenario where a property is an enum.

public class U413ModelBinder : DefaultModelBinder 
{ 
    /// <summary> 
    /// Fix for the default model binder's failure to decode enum types when binding to JSON. 
    /// </summary> 
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, 
        PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 
    { 
        var propertyType = propertyDescriptor.PropertyType; 
        if (propertyType.IsEnum) 
        { 
            var providerValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
            if (null != providerValue) 
            { 
                var value = providerValue.RawValue; 
                if (null != value) 
                { 
                    var valueType = value.GetType(); 
                    if (!valueType.IsEnum) 
                    { 
                        return Enum.ToObject(propertyType, value); 
                    } 
                } 
            } 
        } 
        return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); 
    } 
} 

Code and logic courtesy of this question.

Community
  • 1
  • 1
  • but unlike the question I dont pass an `int` instead I pass a string i.e the named value – user917670 Dec 27 '11 at 14:25
  • @user917670 You will have to implement the logic of the string, but it's the same idea. The Default Model Binder can't assign your Enum parameter of your Action method the value of the string. –  Dec 27 '11 at 14:27
  • does it explain the erratic behavior wherein it works in some cases but doesnt in other cases? – user917670 Dec 27 '11 at 14:43
  • The statement `It looks like the Default Model Binder is not dailed into enumeration` is incorrect. Enums values are integers and c# has not default implicit conversion from string to enum, thus the original question does not work. – Erik Philips Jun 04 '16 at 23:29