Thanks for the reply.
I do see the point about the conversion being opt-in and explicit, however I disagree that using strings or GUIDs would solve the issue.
The solution you posted (Or using GUIDs for that matter) still suffers from the same issue that they are unsafe - As the field is no longer strongly typed as an ObjectId, there is nothing stopping the business logic from putting a random ID in there. This then shifts the point at which the error can occur from the UI input serialisation to the database serialisation level, meaning that there is a larger amount of code which could insert the wrong value.
Ideally any invalid data would be caught (And raised as an error) as early as possible, which in this case would be the SignalR serialisation stuff throwing an exception when an invalid string value is passed in.
Additionally, ObjectIds can be converted to / from strings without any loss and strings are required for a lot of web-based serialisation. (XML, JSON, etc) The error that you'd see is not really any different to passing a non-numeric string into the MVC model binder where it expects an integer - It would correctly fail.
For these reasons I believe that ObjectId <-> string conversion is safe within reason, but I will re-consider if I can do the conversion explicitly in a nice way. Currently I just have a string parameter which I then convert to an ObjectId using ObjectId.TryParse, but I like the idea of just being able to have a method which takes an ObjectId parameter and for it to "just work". What I have now is explicit but it isn't a very clean solution in my opinion.
Thanks,
-Andrew.