05 April 2012

My Impression of ASP.NET MVC Framework - Things To Improve

Been testing out ASP.NET MVC framework as of late and I have to say, it takes a bit of time to get use to it.

Coming from the Java's Spring MVC background, I can't say the transition is easy.  Here are a few things I've noticed so far that I really think ASP.NET MVC needs to improve on.  

1. Controller Naming Convention

By default, ASP.NET MVC uses "DefaultControllerFactory" to find and instantiate controllers with the following convention [Controller Name]Controller (With the suffix "Controller" required. 

Why? It just makes no senses. The strange thing is? I've always named my controllers with the "Controller" suffix in Spring MVC, however, the fact that I HAVE to use it, it doesn't resonant with me. 

Current solution? Develop your own IControllerFactory and get rid of the check for "suffix". See "DefaultControllerFactory" and its related classes for details. I believe the implementation is in "ControllerTypeCache" class, the method to look for is "IsControllerType".  

Extra Work? Yes. 

Wish List:  Please just give us an easy way to turn that off  or see complain #2 below. 

 2. Controller Location

By default, your controllers are suppose to be dropped into /Controller folder in your website.  Me no like!!!!  I like to keep my website clean besides the fact that my designer friend is devilish anal about it as well.  Another thing is? I really would like to separate the controller into a different assembly, in case there is a problem, all I have to do is pass the compiled dll to the clients and be done with it, instead of deploying the whole site which will cause issues to our clients with already configured applications settings and what not. Sure, tell them to not replace this and replace that is easy. Have them follow your instruction is another thing. Support emails in regards to missed steps in upgrade can happen more often than you think.  

Current solution? Thank god. It's changeable. Develop your controller in your own class library and then you have two options (or the use both options at the same time)

a. in Application_Start()  method of global.asax, set

"ControllerBuilder.Current.DefaultNamespaces.Add("[your namespace]")" (and you can add multiple ones);

b. While doing MapRoutes(), for each controller, give it the namespace parameters to look for. This is particular useful if your controller is in a particular namespace. 

Extra Work? Yes, but at least not too tedious

Wish List: Please let us use fully qualified [namspace][class name] or simply scan the already loaded assemblies FAST, so we can avoid all these extra steps. Load controllers from external assembly should in fact be the only way to do it. 

3. URL Mapping. 

Currently, all mapping is done through the global.asax file. That's fine most of the time, but I can imagine overtime, you might change your mind and pretty often at that. Instead of "Tasks/LateTasks/", you might want to change it to "Todos/Late" and with the way it currently is? I have to recompile and deploy it again. 

In Spring MVC, we have a configuration file typically named "Dispatch-servlet.xml" where we might have something like the following

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
         <props>
                 <prop key="/Tasks/LateTasks/*">[controller name for displayinging late tasks]</prop>
                ...
         </prop>
   </property>
</bean>


As you can see, if I decide to make a change, it's almost too easy by modifying the xml file and simply deploy it. No downtime, no restart. 

Current solution? Roll your own ConfigurationSection handlers and hook into the pipeline. Though, I need this to have file cache dependency. Whenever the file is changed, re-load the route tables.  Exactly, how to do, I'm still researching on it. 

Extra work? Most definitely. 

Wish List:   Add a MapRoute configuration option to MVC

4.  View Location

By default, the view has to reside in the default /View folder. Not only, that, your html page has to be under a sub-folder named after your controller name. So if you have a Task Controller, your page has to be under /View/Tasks/ folder. 

Now suppose, you are re-designing your page structure, and you suddenly decided that the name "Tasks" is too broad of a term and you want to re-name it to "Todos", that means, you have to change your controller name from "TasksController" to "TodosController" and then in your MapRoute function, again, you have to change the controller name. 

Currently Solution: Implement your own versions of RazorViewEngine, however, you can only do it to certain extend such as changing the "/View" folder to say "/" root folder and without a configuration file, you still have to physically change this class to hard code the folder name such as "/Todos/" into it as RazorViewEngine only provides [conroller name] & [action name] to the derived classes. It lacks the association of [controller name] to folder or file names directly.  

Extra Work: Yes. 

WishList: Have a configuration file where we can associate view locations to controllers. Something looks like

<Controller id="TasksController" ....>
         <MethodName>Index</MethodName>
         <DefaultPath>~/Todos/</DefaulPath>
         <DefaultView>overview.cshtml</DefaultView>
         <SuccessView>...</SucessView>
         <CancelView>...</CancelView>

         <Other_View>...</OtherView>
</Controller>

 

5. View naming convention

Actually, this is not a complain as I'm cool with how they implemented. Enough flexibility. 

By default, your page name has to be the same has your "Action Name".  Of course, that's if you simply return View(). You can always return View(viewName). 

*Note: To redirect to a view in a different folder, you can do

RedirectToAction(new {controller="home", action="index", id=931,variable="abc"}); 

or

 var otherController = new Controller1(); 
 
return otherController.ActionMethod1();
Wish List:  Though, again as mentioned in #4. It will be much nicer to make this a configurable option. Give it an alias, such as "SuccessView" or "ErrorView" and point it to a page in the same directory or a view in a different directory. in Spring MVC, we can do this in the configuration file

<SuccessView>redirect:/dashboard/overview.html</SuccessView>

Having the word "redirect" there is very convenient, so I don't have to hard code RedirectionAction method in my "Action Method". 

That's it for my first week of using MVC. To be continued. 




 

 

 






 

 
Anonymous comments are disabled