A step by step tutorial on how to use AngularJS with ASP.Net MVC
Precap
I have started this as a multi-post tutorial, where in the previous part we have created a minimal project in Visual Studio 2015 using Web Applications Empty template with MVC folders and references. The application is running now and show Hello World!. You can read that post part 1, part 2 and part 3 in case you have not gone through that already. Let’s continue the idea …
For Web … Smaller and Lesser is Better
In the previous posts, we have reached to a point where we have included the required JavaScript libraries to the project using bower. All these files are in their respective folders under bower_components for the project, but they are not referenced in the page and are not served to the client with the html page. In this post we will be focusing on the way to deliver these files optimally to the client by using the asp.net web optimization bundles.
System.Web.Optimization contains a Class named BundleCollection, where we can add script and style bundles containing the files we would like to bundle together and serve on a single request, compressed and obfuscated. When I work with ASP.Net, I use this technique to minify and uglify the styles and scripts one the fly as compared to doing that in advance using different compressors and obfuscators. This gives me control on may be dynamically include the script files and conditionally compressing the files, e.g. compress while in production but not in development environment.
Get Them all Squeezed …
First of all we need to add this optimization library as a NuGet package (yes, you read it all right, NuGet is the right choice here in this scenario for maintaining the .net library packages). Open NuGet Manager for the project and search for “Optimization” in the browse tab. Select and install “Microsoft.AspNet.Web.Optimization” package from there as show in the image below. It may install a few required dependencies along with that, which you should allow it to do so.
In App_Start Folder create a new class named BundleConfig.cs and add the below code to it
using System.Web.Optimization; namespace SchoolWorld.Web.App_Start { public partial class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { // bundle scripts bundles.Add(new ScriptBundle("~/js").Include( "~/bower_components/jquery/dist/jquery.js", "~/bower_components/angular/angular.js", "~/bower_components/angular-ui-router/release/angular-ui-router.js", "~/bower_components/bootstrap/dist/js/bootstrap.js")); // bundle styles bundles.Add(new StyleBundle("~/css").Include( "~/bower_components/bootstrap/dist/css/bootstrap.css", "~/Content/Site.css")); } } }
The code above is self explaining, but for your clarity, we are creating 2 bundles, one for scripts and another for styles. These bundles when referenced in the view, will render the links to compressed / uncompressed files.
Bundle the Bundles with MVC View …
In above step we have created the bundles, now we have to register these bundles to the request handler and include them in the _Layout.cshtml. Open the Global.asax and replace the contents with the code below:
using SchoolWorld.Web.App_Start; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace AngularJSwithMVC { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } }
Open web.config under the Views folder (not the one in the project root folder) and add the namespace “System.Web.Optimization” under namespaces section.
<namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.Optimization" /> <add namespace="AngularJSwithMVC" /> </namespaces>
Open _Layout.cshtml and replace the code with the one shown in below snippet
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My AngularJS App</title> @Styles.Render("~/css") </head> <body layout="column"> @RenderBody() @Scripts.Render(new string[] { "~/js" }) </body> </html>
Run the application and inspect the source using your browser’s development tools, you should see the output similar to this one
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My AngularJS App</title> <link href="/bower_components/bootstrap/dist/css/bootstrap.css" rel="stylesheet"/> <link href="/Content/Site.css" rel="stylesheet"/> </head> <body> Hello World! <script src="/bower_components/jquery/dist/jquery.js"></script> <script src="/bower_components/angular/angular.js"></script> <script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script> <script src="/bower_components/bootstrap/dist/js/bootstrap.js"></script> </body> </html>
Where is the Compression?
You can see in the above output that all the files we included in the bundles are included as it is, so where is the compression? Remember I have told you earlier that the files can be compressed conditionally, and here the default condition is Debugging mode. Edit the main web.config file and disable the debugging by setting compilation tag’s debug attribute to false under the system.web section. At this time if you run the application again you will see, what we are trying to achieve.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My AngularJS App</title> <link href="/css?v=HWyqqv78-MmGFJmETyURBTAYJwiQc_rP-elFPK5iVQU1" rel="stylesheet"/> </head> <body> Hello World! <script src="/js?v=LNUvXDJjMnfrdY07Ho_exMpbrd7-3Pn1CNPHdzuuDy41"></script> </body> </html>
Both the bundles are replaced with a single link and if you inspect the response of these links in the network tab of your bowsers development tool, you will see that the contents are compressed and obfuscated.
I am loving it … are you?
We have started seeing it … isn’t it? The mixture of both the worlds are coming out with a pleasant color. I will conclude this post here and leave you to play more with this project a little more. In case you are not getting a hang of it, I am here, through your questions and I will try to answer them. Remember your comments will be a great help to me directing the right path for the upcoming tutorials and posts. Keep a watch and let me know what you want to learn more. I will add the links of the remaining parts of this posts below here for your reference and navigation. Till next time … Cheers!
Series Links
Part 1 Part 2 Part 3 Part 5 Part 6 Part 7 Part 8 Part 9 Part 10 Part 11