MVC CustomModelBinder, Action with same property names - An item with the same key has already been added

230 views Asked by At

I have created a custom model binder to bind int, to handle when the string value is greater than int.maxvalue - we have a lot of legacy code using UpdateModel, and this method throws an exception if the string value to be converted to an int is greater than int.MaxValue. If I modify the call to UpdateModel to be TryUpdateModel, the update fails gracefully and an error is displayed in the view, but I want a more meaningful error message - hence the custom model binder. The model binder works fine, however I have an Action similar to the following

   public ActionResult List(ListCriteria criteria, int page)

The class ListCriteria has a property on it as follows

public int Page { get; set;}

My custom model binder implements IModelBinder. Similar to quite a lot of samples, it is implemented similar to the following.

public class IntModelBinder : IModelBinder {
public object BindModel(ControllerContext controllerContext, 
    ModelBindingContext bindingContext) {
    ValueProviderResult valueResult = bindingContext.ValueProvider
        .GetValue(bindingContext.ModelName);
    ModelState modelState = new ModelState { Value = valueResult };
    object actualValue = null;
    try {
        actualValue = Convert.ToInt32(valueResult.AttemptedValue, 
            CultureInfo.CurrentCulture);
        }
        catch (FormatException e) {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

When the action is called, the model binder throws an exception on this line:

bindingContext.ModelState.Add(bindingContext.ModelName, modelState);

and the exception message is "An item with the same key has already been added". Obviously this is because the Page property on the ListCriteria object has already been bound, and added to the dictionary - when the page parameter is bound and added, the exception is thrown.

How should this be implemented? Shouldn't it be possible to have properties with the same name at different levels of the object hierarchy?

In my case it turns out that the Page property and the page parameter perform the same function, so the latter cna be deleted - however it is concerning that it might rear its head elsewhere...

0

There are 0 answers