Model Binding MongoDB ObjectId with ASP.NET MVC

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.

Posted on by Joe in ASP.NET, C#, MongoDB, MVC

12 Responses to Model Binding MongoDB ObjectId with ASP.NET MVC

  1. Van Nguyen

    You may need [ModelBinderType(typeof(ObjectId))] if you are using Autofac.

  2. Joe

    Thanks Van

    How did you come across my blog?

  3. Jing

    you put the link in thesource code, mate. i’m here to blame you. 😀

  4. Joe


    I just noticed this code was added to the project with a link back here, but I didn’t do it.


  5. Liam

    Hi Joe,

    You mentioned this in your post:

    “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.”

    I happen to have run into exactly this problem, as I am having problems getting Automapper to convert the ObjectId bson from my domain to my DTO. Can you give me an idea as to how you have tackled this?



  6. Joe

    Hey Liam

    How are you trying to convert it exactly? From ObjectId in the domain model to string in the ViewModel?

    Just just need to set up your mapping configuration:

    Mapper.CreateMap().ForMember(d => d.MyProperty, o => o.MapFrom(s => s.MyProperty));


  7. Liam

    Thats right.

    I have a domain object:

    public class Car
    public ObjectId Id;
    public string Color

    and want to map to the Dto object like this:

    public class CarDto
    public string Id;
    public string Color;

    I am currently doing this:

    .ForMember(d => d.Id, o => o.MapFrom(s => s.Id.ToJson()));

    Also at some point I will want to be able to do:

    Mapper.CreateMap<IEnumerable, IEnumerable>();

    Should I create a custom converter from string to ObjectId and vice-versa?



  8. Joe


    You don’t need to call ToJson, unless you want it stored like that? In my comment above it just implicitly casts to string.

    With lists and AutoMapper you just need to set up the mapping for the domain to model like you are doing above, then when actually performing the map do:

    var model = Mapper.Map<IEnumerable<Domain>, IEnumerable<Model>(myDomainObjectList);

    You don’t need to set up any specific mapping for lists.

    If you want to map a string back to an ObjectId in the map just do:

    Mapper.CreateMap().ForMember(d => d.MyProperty, o => o.MapFrom(s => new ObjectId(s.MyProperty)));

    This uses the constructor of ObjectId that takes a string as an argument. Be careful mapping view models back to domain objects though, you don’t want it clearing out domain object properties that aren’t set in your model.


  9. Joe

    Sorry for the code snippets above getting cut off, you can copy and paste them out. Without the code tag wordpress was doing weird things with the multiple angle brackets.

  10. Liam

    Cheers for the explanation Joe. Going to have another crack at it this evening.

    Much appreicated.

  11. Dave

    Thanks for the MongoDB ObjectId model binding fix. Just what I needed…

  12. nikolai

    Consider using BsonRepresentation attribute.

    Make your id property plain .net string and decorate it with BsonRepresentation attribute:

    public class Comment
    public string CommentId { get; set; }

    public DateTime Date { get; set; }

    public string Author { get; set; }

    public string Detail { get; set; }

Add a Comment