I have a class library which includes a custom MVC model binder to instantiate various concrete types which derive from an abstract class. The model binder is almost identical to the one described in this post.
It works fine when using it from within the same Visual Studio Solution that also includes an MVC web application for testing.
My problem is that having created a nuget package from the assembly and included it in a totally separate MVC application the model binder no longer works, despite having configured it correctly in Global.asax.cs.
After some hair pulling I recreated the model binder directly in the separate MVC app, and as I was doing so I noticed that the overridden CreateModel() method in the binder is protected. It now gets executed and I suspect the protected keyword has something to do with it but I would like someone to explain why exactly.
Even with the 'local' modelbinder there are more problems. When it executes, and tries to instantiate the concrete object, I get an exception Could not load type XXXX from assembly { separate MVC project assembly name} so it seems the model binder is unable to load types from outside its own assembly.
Can anyone give me more information on why this happens and what I can do to work around it? Bearing in mind I need the model binder and models to reside in the class library not in the MVC assembly.
I had the same problem as you did, binding to models in a different assembly, but I needed a different solution. I used the same model binding example that you linked to, and I also got the same exception: Could not load type XXXX from assembly
I ended up needing to use the AssemblyQualifiedName for each concrete type. So my views contain this:
#Html.Hidden("ModelType", Model.GetType().AssemblyQualifiedName)
Instead of this:
#Html.Hidden("ModelType", Model.GetType())
I'm still wondering why this was necessary, since the default model binder can load types from the assembly in question.
OK so I was being stupid. It turns out that a few assumptions led me on a wild goose chase.
The ModelBinder was executing correctly to start with. My viewmodel had nested properties which were also abstract base types and required the model binder but I hadn't put the hidden fields in the view to identify their concrete type, nor had I added them to the Global.asax configuration. Once I did this everything started to work as expected.
Related
Hi friends in webapi using mvc format i created one webapi project here i added autofac resolver to resolve DI(dependency injection) its working fine then in next step i took this dlls and created new project for this i added the dlls now in this project i added one controller but it is showing the error 'x(controller name)' Type controller does not have a default constructor but for this many people given solution for this add new bootstrap class(which contain autofac for di resolve) but i am inherting my old global.asax file from my current global.asax file so i think dont want to add again all the stuff the autofac resolver will get from old dlls so i find many solutions but now luck can any one help me
Note : please ask me incase of any clarity (my english is not good excluse me for this)
The Mistake I did is Spelling mistake this is if Controller name is SampleController i am putting SampleContoller (missing r in Controller splleing) thats it now i corrected splleing now its working fine
I've decided to use custom template engine with Spring MVC framework.
my templates implemented in java and have method for rendering into String:
public String render(Map context);
how to configure spring to make them available in Controller beans as views, for example like:
ModelAndView modelAndView = new ModelAndView("activationPage"); // - view name which will actually be java class name reference.
modelAndView.addObject("validationResult", validationResult);
return modelAndView;
Model will be passed as context in code connecting spring and my template engine.
You need to implement org.springframework.web.servlet.View (which should be easy, you already have something very similar to the render method it needs), as well as org.springframework.web.servlet.ViewResolver, which maps the view names (e.g. "activationPage") on your custom views.
Once you have that, drop a bean of your ViewResolver class into the context, and (unless you've done something else that gets in the way) it should automatically be picked up by Spring and should just work. if you have other ViewResolvers already in there, they may get into a fight over who gets to resolve the view, in which case ask a new question.
Hi I am the author of Rythm template engine, about half year ago I am having the same requirement like you. What I did is to read the source code of Velocity and Freemarker view of SpringFramework. And then create the Rythm view for spring following their approach.
It's easy to follow something that is already there, and it makes your implementation in good quality to follow the official module. Good luck on you :-)
I provide a highly customisable application to my clients which is working totally by itself. But If one my client wants to overwrite any Controller, I want to replace my implementation by theirs. However just overwriting the controller causes an ambiguous definition of mappings.
I have been using Component Scanning to load beans.
The potential solutions came to my mind are:
Using component scanner with excluding by a custom filter? (This seems not so easy)
Using a xxxxPostProcessor to remove some beans? (How?)
Any help?
If I got your Question properly,
You can differ implementation by changing URL to particular Implementation name
Say Telecom is interface and AirtelImpl and RelianceImpl are Controllers then
Your request mapping
#RequestMapping(value= "/airtel/doBilling")
#RequestMapping(value= "/reliance/doBilling")
In this way, Implementation flow will differ.
I have followed these steps:
Created a custom annotation: #Devoted
Created a custom ImportBeanDefinitionRegistrar. Iterated already registered bean definitions to find out `#Devoted #Controller's and removed them.
Based on a request I will provide implementation details.
I have an WebApi application that contains some controllers (they are registered using the extension method RegisterApiControllers). This application references another assembly that contains other controllers that I don't want to expose(I have checked that they are not registered in the container). It happens that both have an OrderController, and when I try to access the /api/Order url, I get an exception "Multiple types were found that match the controller named 'order'." and the stack trace shows that I was in DefaultHttpControllerSelector.
I have seen that AutofacControllerFactory used to exist and there was even a ConfigureWebApi that registered it, but it is not anymore present in the default branch.(you can see it here http://alexmg.com/post/2012/03/09/Autofac-ASPNET-Web-API-(Beta)-Integration.aspx)
It seems also that we can not filter the namespace of the route definition in WebApi (it is possible to MVC).
So any idea on how I can use only the Controller registered in my Autofac container and not use the DefaultHttpControllerSelector that seems to scan all referenced assemblies to discover controller?
Thanks
The problem is that registering the controller with autofac is not really related to the routing process. Only once the routing process has identified which controller to dispatch to will Autofac be called to resolve the type.
It looks like, from digging around in the source, that you would need to write a replacement IHttpControllerSelector in order to handle two controllers with the same name. (which really sucks BTW).
You might be able replace the DefaultHttpControllerTypeResolver with an instance that is passed a predicate that filters out the controllers from the assembly that you want to ignore. It's a bit of a kludgy solution but might work.
Actually, you might be able to replace the DefaultHttpControllerTypeResolver completely with one that is based on registrations in your Autofac container. It is a very simple interface, so as long as Autofac have a some kind of discovery mechanism, you should be golden.
public interface IHttpControllerTypeResolver
{
ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver);
}
So we're working on converting some projects at work from Ninject to Autofac, and we've stumbled on something really neat within Ninject that we can't figure out how to do in Autofac. In our application, we have an interface called ISession which is implemented in two different concrete types. One goes to an Oracle database, and the other goes to an MS-SQL database.
We have controllers in our MVC application that need only one concrete implementation of ISession based on which controller they are being injected into. For example:
Bind<IFoo>().To<Foo1>();
Bind<IFoo>().To<Foo2>().WhenInjectedInto<OracleController>();
My question is: how do we achieve the same result in Autofac? When IFoo is injected into any controller, Foo1 should be provided by default, however in one special case, we need Foo2 instead.
Thanks for any help in advance!
With Autofac you can achieve this by doing the registration the other way around. So you should declare that you want to use the "speciel" service when you register the OracleController not when you register the IFoo.
containerBuilder.RegisterType<Foo1>().As<IFoo>();
containerBuilder.RegisterType<Foo2>().Named<IFoo>("oracle");
containerBuilder.RegisterType<OracleController>().WithParameter(ResolvedParameter.ForNamed<IFoo>("oracle"));
The Named registration "oracle" ensures that the default IFoo instance will be Foo1 and you only get Foo2 when you explicitly request it by name.