Merging ASP.Net MVC and AngularJS Routing

This post briefly describes one way to ‘mix’ ASP.NET MVC approach to web applications and AngularJS approach. To be clear, each of these technologies approaches web application development from different perspectives:
ASP.NET MVC is a server-side page rendering framework.
AngularJS is a client-side page rendering framework.

The difference between the two allows them to work together but also introduces one side effect related to page request routing.

In a recent project, I was asked to research using both of these frameworks together on the same product since one group within the company wanted to move towards AngularJS for small web apps but another group only has the ASP.NET MVC skill set.  I wanted to see how a simple project with both frameworks would look like.

It is very easy to use both frameworks in Visual Studio 2012 by simple using the an ASP.Net MVC 4 project template and then importing the ‘angularjs’ nuget package.  The details of how to use AngularJS and MVC is out of scope of this post but one issue that you will run into (and the subject of the post) is how to deal with AngularJS routing to show partial HTML pages(views) which reside on the server.

The scenario is that you have an initial web page, Index.cshtml, which is a typical Razor page that also include AngularJS directives

Example Index.cshtml

Example Index.cshtml

Note: The Razor syntax on line 2 and the angular directives on lines 17 and 20

Once this page is rendered in the browser, AngularJS will load the default route as defined when the module was created:

var NbCapp = angular.module('NbC', ['ngRoute', 'ui.bootstrap']);
NbCapp.config(function ($routeProvider) {
 $routeProvider
 .when('/ondemand', {
 controller: 'onDemandController',
 templateUrl: 'ondemand/ondemand'
 })
 .when('/results', {
 controller: 'resultsController',
 templateUrl: 'results/results'
 })
 .otherwise({ redirectTo: '/results' });
});

Notice that the ‘templateUrl’ value doesn’t have an ‘.html’ extension as you would expect in a ‘pure’ AngularJS application. This is because when the Ajax request is sent to the server to retreive the partial view, it is processed by the ASP.NET MVC request pipeline, which expects it to follow a specific
naming convention:

in the App_Start/RouteConfig.cs file generated by the MVC template:

routes.MapRoute(
 name: "Default",
 url: "{controller}/{action}/{id}",
 defaults: new { controller = "Index", action = "Index", id = UrlParameter.Optional });

So, in order for AngularJS to load partial views, you will need to create the views as MVC *.cshtml pages so that the default routing will find the page (prevents a 404 error). The contents of the *.cshtml page can be the regular HTML snippets with AngularJS directives but now you have to create empty Controller classes as well.  This just adds extra noise to the application layout and when a new developer looks at this for the first time, it looks like a typical MVC app and nothing like the best practice AngularJS layout

Example Project Layout: MVC or AngularJs?

Example Project Layout: MVC or AngularJs?

Conclusion:
It is simple to mix these two technologies but in the end it will look like an ASP.Net MVC project and that will eventually become a maintenance problem.

Here are two ways to address this problem:

  • Configure IIS to skip the MVC processing for files with an *.html extention
  • Customize the routing behaviour to treat *.cshtml and *.html differently.

I have not explored either of the above options.  That is left as an exercise for the reader.

 


5 responses to “Merging ASP.Net MVC and AngularJS Routing

Leave a comment

Design a site like this with WordPress.com
Get started