One of the really cool features that is introduced with MVC is modelbinding. The DefaultModelBinder already gives you a great start for binding request data to models but wouldn’t it be really cool if we could have an UmbracoModelBinder?
If you don’t know about Glass or you don’t know about Modelbinders, I recommend you google it up before you read this post, or after if you are triggered.
So first let’s talk a bit about the plan. I aim to extend the DefaultModelBinder and if I recognize the model as one of my Glass models then I’ll get the current umbraco document and try to map the model using the UmbracoService. For this I’ll need to take at least 3 steps:
Create the UmbracoModelBinder
First I start by creating my UmbracoModelBinder class with the DefaultModelBinder as base class and I override the BindModel method like this:
Then we need to check if the current Model is assignable from our base model, try to map it and return it like the image below. An important part is that I use InferType to get the Item so the ModelType doesn't need to be exact BaseCommon but needs to derrive from BaseCommon.
Register the UmbracoModelBinder
To tell Mvc that it should use my custom ModelBinder I added a BootstrapperTask which helps me execute stuff on application start but it could also be done in the Global.asax. In the execute method we only need one line of code which is pretty simple. I set the DefaultBinder property to our custom Binder and we’re all set.
One last thing to do to is apply this in my controller: add a template specific action method and add the model as parameter:
Here you can see the difference in using the regular Index method where I use the service to get the model and below that the BlogPage method with the model as parameter which will be set by our UmbracoModelBinder. Using this methods takes away the hassle of instantiating an UmbracoService and mapping the item.
Note that I am requesting BlogPage which implements BaseCommon and because I use InferType the ModelBinder will give me a model of BlogPage instead of BaseCommon.
When I created this feature I ran into some issues with the BlogPage action not getting called and it took me a while that Umbraco’s Route Hijacking works with TemplateName for the action and not DocumentTypeAlias, so for me to get this working I had to add a Template in Umbraco and assign it to my BlogPage documentType. I’ll never use the Template since I hijack the route and call my own view so I’ll investigate and see if I can break into Umbraco’s routing and use my own rules. Hope to blog about that sometime soon.