My MVC app tends to have a lot of ajax calls (via JQuery.get()). It's sort of bugging me that my controller is littered with many tiny methods that get called via ajax. It seems to me to be sort of breaking the MVC pattern a bit--the controller is now being more of a data access component then a URI router.
I refactored so that I have my 'true' controller for a page just performing standard routing responses (returing ActionResponse objects). So a call to /home/ will obviously kick up the HomeController class that will respond开发者_StackOverflow中文版 in the canonical controller fashion by returning a plain-jane View.
I then moved my ajax stuff into a new controller class whose name I'm prefacing with 'Ajax'. So, for example, my page might have three different sections of functionality (say shopping cart or user account). I have an ajax controller for each of these (AjaxCartController, AjaxAccountController). There is really nothing different about moving the ajax call stuff into its own controller class--it's just to keep things cleaner. on client side obviously the JQuery would then use this new controller thusly:
//jquery pseudocode call to specific controller that just handles ajax calls
$.get('AjaxAccount/Details'....
(1) is there a better pattern in MVC for responding to ajax calls?
(2) It seems to me that the MVC model is a bit leaky when it comes to ajax--it's not really 'controlling' stuff. It just happens to be the best and least painful way of handling ajax calls (or am I ignorant)?
In other words, the 'Controller' abstraction doesn't seem to play nice with Ajax (at least from a patterns perspective). Is there something I'm missing?
While you might put Controller
on the end of it to make ASP.NET MVC's routing magic work, I tend to do what you've already done--except when I read AjaxCartController
I think to myself AjaxCartPresenter
(as in the Model-View-Presenter pattern commonly seen in WinForms). That is, this "controller" is not controlling but instead unashamedly tied to the view interface. But, unlike the view, the controller presenter is testable.
When we AJAXify a Web page, we're turning it into something that can react in a fine-grained manner, so fine-grained methods are okay. Fined-grainedness is the point and the whole reason it was invented. We are deliberately walking away from REST for a particular scenario because that particular pattern is not solving the UI requirement at hand, instead choosing an RPC-like model. They are just patterns, one is not going to be better than the other in all situations, even if our technology stack might be pushing us toward one over the other. (Indeed, HTTP itself does better in chunks/pages/entities/representational state transfer documents.)
Mentally, you can treat these pages as if they were forms in a WinForms application; the fact that these methods sit in a "controller" is just an artifact of and concession toward the technology being used. (If it super-duper bothers you, you could roll the AJAX methods into an IHttpHandler
and bypass MVC entirely, but why throw away the automatic routing/instantiation/method lookup and make it difficult for yourself? It would be architecturally 'clean' and pure but of dubious benefit.)
... at least, that's how I rationalize it to myself =)
If you have too many fine-grained requests, you might want to have one Controller Action method to service all the calls. You might use a 'switch' in the method to determine the call type and service it accordingly instead of having a zillion tiny methods. You might even use explicit string constants instead of numbers for the switch variable.
精彩评论