This is possbily related to my previous post around odd grid binding behaviour (waiting for approval).
I have an MVC 5 web app and a model with child objects and am binding this in a Kendo grid control. When attempting to update a child row the model binder appears to be throwing an error, and the call to the update method in the controller never gets fired.
"System.MissingMethodException: Cannot create an instance of an interface". The key indicator seems to be "MissingMethodException: Cannot create an instance of an interface. Object type 'Csla.Core.IParent"
So it looks like it's failing trying to work out the parent property of the child. .Net can't spin up an interface - it needs the real concrete class.
Now I don't think this is a CSLA issue, but rather a Kendo grid + Csla binder interaction going on here, and I know grids and binding always throw some fun issues into the mix. I have set the MVC default model binder to use the Csla version.
Any ideas? The razor form binds directly to the model - not using the CslaViewModelBase (maybe I can try that).
I've used this technique kendo grid + poco (plain old class objects) on another project and this binding action approach all works fine. So is it kendo + csla model binder problem?
I'll post this into the kendo forums too, but I know I'll get the Csla insights here.
Here's part of the stack trace.
[MissingMethodException: Cannot create an instance of an interface.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +66
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +554
[MissingMethodException: Cannot create an instance of an interface. Object type 'Csla.Core.IParent'.]
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +630
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1136
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +633
Castle.Proxies.DefaultModelBinderProxy.BindModel_callback(ControllerContext controllerContext, ModelBindingContext bindingContext) +45
I think we had something similar in MVC2 or 3. Basically what we had to do was include the .Net type information so that if it saw one of our interfaces or abstract base classes, it would look at the type information (which got embedded in a data- attribute).
That said though, the Parent property shouldn't be used in your view at all, and I can't really think why it would be necessary. What does your view look like, do you use .Parent anywhere?
Thanks. Well the parent property gets serialized down by default in by the Ajax json serializer when the grid is loaded. I did think about customizing the serializer to remove it but after more research around kendo grid and thinking about the problem overnight I realised I'm partly being stupid.
Although inline grid editing (MVC) gives the illusion I'm editing a child, in reality we are editing one object. The kendo grid posts back the row being edited, not the whole model tree. So the MVC model binder has no idea that its a child object with a parent - a parent of what type - it can't figure it out? As you say, maybe you can do something to help it work it out. Also, if I did get pass the binder remember I'm trying to new-up a child here, which my csla model should not allow, unless I tweak and frig it, which is a bad workaround IMHO. So, really here, the use case is I'm editing a root businessbase object, and if I really want to do that I should create a root version object that allows this rather than trying to do it as a child model.
The Kendo grid MVC version also really does NOT support "complex models".
In the end, the solution I used was to use a viewmodel. So when the grid loads, I map (using the wondeful AutoMapper) my children into a list of viewmodels (simple poco's) and bind that to the grid. The kendo grid can then post the child vm back nicely and then I load up my parent model and its children, fidn the model I'm editing and map the changes back from the vm into the child - thus I get the csla business rules firing as required.
The viewmodel works for me in my MVC world. If I was doing a WPF UI I know from experience that the grid controls do tend to support complex objects, and that a WPF grid would typically be able to do a save call on the parent which would then ripple down to the children and save our amended child.
Oh, are you directly serializing a Csla object to a web browser or something? The view model approach is correct, you shouldn't expose your Csla model directly from a web service: http://www.lhotka.net/cslanet/faq/ObjectsAsServiceContract.ashx
Its an MVC razor view so its ok to send a csla model down. Not a web service.
But thanks again.
Ok, then I'm not clear on where the AJAX serializer comes into play. At any rate, the Parent property shouldn't be getting sent to the browser at all.
Copyright (c) Marimer LLC