Popular blog tags

If you’re using the MongoDB C# driver with ASP.NET MVC and have a property of type ObjectId in your model you will get the following error when trying to bind back to the model.

The parameter conversion from type ‘System.String’ to type ‘MongoDB.Bson.ObjectId’ failed because no type converter can convert between these types.
This can easily be resolved by creating a custom Model Binder which I’ll explain how to do in this article.

Normally I try not to use third party library types in View Models, and stick to simple types, so I’d probably have the ObjectId in my Domain model which is represented as a string in my View Model, then I’d use Automapper to manage the conversion.

Anyway, that’s not what this article is about, if you do choose to use an ObjectId in your View Model, you may have a hidden field on your form for that property for updating an object. The hidden input will get rendered correctly with the ObjectId as a string, but when you come to bind back to the model you’ll get some problems.

To create a custom Model Binder, create a class that implements the IModelBinder interface. I have created a class called ObjectIdBinder which looks like this.

public class ObjectIdBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        return new ObjectId(result.AttemptedValue);
    }
}

What this does is gets a ValueProviderResult for the given property represented by ModelBindingContext.ModelName. I then create a new ObjectId using the ValueProdiverResult.AttemptedValue which gets the raw value converted to a string.

This is all that is required for the Model Binder itself, all that’s left to do now is register it in the Global.asax Application_Start method.

protected void Application_Start()
{
    ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdBinder());
}

Now you can successfully bind back to a model with an ObjectId property type.