AngularJS with ASP.Net MVC (Part 7)

A step by step tutorial on how to use AngularJS with ASP.Net MVC

Precap

I have started this as a multi-post tutorial a few posts back. In the previous parts we have created a minimal project in Visual Studio 2015 using Web Application’s Empty template with MVC folders and references. The application is running now with the bootstrapped UI containing a navigation of 3 pages. It has been demonstrated how differently application behaves with MVC routing and AngularJS routing. You can read those posts part 1part 2part 3part 4part 5 and part 6 in case you have not gone through that already. Let’s move to next step where we will be replacing the AngularJS routing with ui-router’s states.

Why ui-router?

It is very easy to explain the benefits of using ui-router over angular-route with an example in hand rather telling each and every aspect of the comparison. Moreover to teach AngularJS and its features is beyond the scope of this series. So let’s begin with replacing the angular-route with ui-router.

First Thing First

In the Index.cshtml we have a div tag with ng-view atribute, which we have to replace with ui-view. This works as the placeholder for the views to be rendered by the ui-router states. Once you update, your Index.cshtml should look similar to this snippet now.

<div ui-view></div>

In part 3 of our guide we have already included the required libraries in the project, so we are not looking that direction. So, now we can replace the ngRoute module with ui.router in the app module. Open the app.module.js and update the file as show in the snippet below.

(function () {
    'use strict';

    angular.module('app', ['ui.router']);
})();

Define ui-router States

We have already defined the angular routes in app.config.js file in part 6 of this series, which we will be removing. Now create a new file named app.route.js adjacent to the app.config.js and paste the code from the below snippet in there.

(function () {
    'use strict';

    angular.module('app')
        .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise('/');
            $stateProvider
                .state('home', {
                    url: '/',
                    templateUrl: '/Home/Home'
                })
                .state('page1', {
                    url: '/Page1',
                    templateUrl: '/Home/Page1'
                })
                .state('page2', {
                    url: '/Page2',
                    templateUrl: '/Home/Page2'
                })
                .state('page3', {
                    url: '/Page3',
                    templateUrl: '/Home/Page3'
                });
        }]);
})();

Also, remember to include this new file in the BundleConfig.cs. Update your app.config.js file as below.

(function () {
    'use strict';

    angular.module('app')
        .config(['$locationProvider', function ($locationProvider) {
            $locationProvider.hashPrefix('');
        }]);
})();

Run the application and you will find no difference at all in the behavior  of the application. this shows that the angular-route can be directly replaced by the ui-router without deviating from the applications functionality.

We will be extending this simple application to a more meaning for application which will be demonstrating more aspects of the ui-router and how the MVC views can be used as templates for different parts of the same view. yes that’s the one of most powerful feature of the ui-router, render multiple view templates in the same page. But this is the topic of our next post.

I am hoping that you might have got a gist of the concept of using AngularJS with MVC, but there are more to come, so wait for the next post and leave your comments in case you have any questions till now. I will really appreciate your feedback so that I can improve my content and help you all in a right way while producing more accurate articles.

Cheers!

Series Links

Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 8 Part 9 Part 10 Part 11

AngularJS with ASP.Net MVC (Part 6)

A step by step tutorial on how to use AngularJS with ASP.Net MVC

Precap

I have started this as a multi-post tutorial a few posts back. In the previous parts we have created a minimal project in Visual Studio 2015 using Web Application’s Empty template with MVC folders and references. The application is running now with the bootstrapped UI containing a navigation of 3 pages. You can read those posts part 1part 2part 3part 4 and part 5 in case you have not gone through that already. Let’s move to next step where we will be delegating the routing at client side using AngularJS.

Start Using AngularJS

During this post we will be creating an AngularJS module and tell our ASP.Net MVC application to use that. It will do client side routing while rendering the views from the MVC actions.

AngularJS Routing

We are required to add another library here, which we need for the AngularJS routing. Open the command prompt and execute the below command in the project root folder. This will install a new folder in the bower_components, which we need to include in the project.

bower install angular-route --save

Modify Bundles

Open BundleConfig.cs file and include the new JavaScript file in there for the js bundle as shown in the snippet below.

 "~/bower_components/angular/angular.js",
 "~/bower_components/angular-route/angular-route.js",
 "~/bower_components/angular-ui-router/release/angular-ui-router.js",

Define AngularJS Module (app)

Create a new file named app.module.js under Scripts -> app folder (we have to create folder named app in case that is not already there) and put below code in there.

(function () {
    'use strict';

    angular.module('app', ['ngRoute']);
})();

Module Configuration

Next step is to configure the routing for AngularJS. Create a new file named app.config.js under Scripts -> app folder and add the blow code to it.

(function () {
    'use strict';

    angular.module('app')
        .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
            $locationProvider.hashPrefix('');
            $routeProvider
                .when('/', {
                    templateUrl: '/Home/Home'
                })
                .when('/Page1', {
                    templateUrl: '/Home/Page1'
                })
                .when('/Page2', {
                    templateUrl: '/Home/Page2'
                })
                .when('/Page3', {
                    templateUrl: '/Home/Page3'
                });
        }]);
})();

Once you are done creating these files, include them in your bundle by editing the BundleConfig.cs file as shown below.

"~/bower_components/angular-ui-router/release/angular-ui-router.js",
"~/bower_components/bootstrap/dist/js/bootstrap.js",
"~/Scripts/app/app.module.js",
"~/Scripts/app/app.config.js"

Include AngularJS module in HTML

We are ready with the AngularJS module and now we need to include the module in the _Layout.cshtml. To do so, please modify your _Layout.cshtml file as per the code snippet below.

<!DOCTYPE html>
<html ng-app="app">
<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>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-nav">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">AngularJS with ASP.Net MVC</a>
            </div>
            <div class="collapse navbar-collapse" id="main-nav">
                <ul class="nav navbar-nav">
                    <li>
                        <a href="/#/Page1">Page 1</a>
                    </li>
                    <li>
                        <a href="/#/Page2">Page 2</a>
                    </li>
                    <li>
                        <a href="/#/Page3">Page 3</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    @RenderBody()
    @Scripts.Render(new string[] { "~/js" })
</body>
</html>

Replace the content of Index.cshtml as per the snippet below

<div ng-view></div>

Modify the HomeController.cs while adding a new Action method named Home. Please not that we are now returning PartialView() in place of View() from some of the Action Methods.

using System.Web.Mvc;

namespace AngularJSwithMVC.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Home()
        {
            return PartialView();
        }

        public ActionResult Page1()
        {
            return PartialView();
        }

        public ActionResult Page2()
        {
            return PartialView();
        }

        public ActionResult Page3()
        {
            return PartialView();
        }
    }
}
<!-- Home.cshtml -->
<h1>Home Page</h1>

The Output …

P2122_001

As you can see in the output, we are now seeing the application from the AngularJS prospective. Here all the links are ‘#’ hashed where on clicking the Page links, it is only changing the view rather than loading the complete page again.

In case you have any questions till this point, you can always leave the comments and I will try to answer them as soon as possible. I will continue on the next part of this series and leave you here with your brain to play with the idea. In the next part you will see another way of doing the routing, by using ui-router, another AngularJS library most commonly used in large scale modular applications. Bye till then!

Series Links

Part 1 Part 2 Part 3 Part 4 Part 5 Part 7 Part 8 Part 9 Part 10 Part 11

AngularJS with ASP.Net MVC (Part 5)

A step by step tutorial on how to use AngularJS with ASP.Net MVC

Precap

I have started this as a multi-post tutorial a few posts back, where in the previous parts we have created a minimal project in Visual Studio 2015 using Web Application’s Empty template with MVC folders and references. The application is running now and show Hello World! with all the required scripts and styles pushed to client in best optimal way. You can read those posts part 1part 2part 3 and part 4 in case you have not gone through that already. Let’s design a minimal layout here in this post.

Boot it with Bootstrap

Twitter Bootstrap is a well know library to provide components to bootstrap your web application like navigation, buttons and input controls styles. We have already included bootstrap library as a bower package in our application and is getting pushed to client side already. We just need to use it to design our sample application.

Open your _Layout.cshtml from Views -> Default folder and add the snippet shown below just above the @RenderBody().

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-nav">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="">AngularJS with ASP.Net MVC</a>
            </div>
            <div class="collapse navbar-collapse" id="main-nav">
                <ul class="nav navbar-nav">
                    <li>
                        <a href="/Home/Page1">Page 1</a>
                    </li>
                    <li>
                        <a href="/Home/Page2">Page 2</a>
                    </li>
                    <li>
                        <a href="/Home/Page3">Page 3</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    @RenderBody()
    @Scripts.Render(new string[] { "~/js" })
</body>

MVC Controller – Actions

Create 3 new actions in the HomeController.cs as show below in the snippet and add corresponding View for them.

using System.Web.Mvc;

namespace AngularJSwithMVC.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Page1()
        {
            return View();
        }

        public ActionResult Page2()
        {
            return View();
        }

        public ActionResult Page3()
        {
            return View();
        }
    }
}

Views

P2062_001

Index.cshtml
<h1>Home Page</h1>

Page1.cshtml
<h1>Page 1</h1>

Page2.cshtml
<h1>Page 2</h1>

Page3.cshtml
<h1>Page 3</h1>

And it is a MVC Application …

P2062_002

That’s all, we are ready at this point with our base sample MVC application and can see that all the views and routing is presented by ASP.Net MVC. If we are navigate to pages, we can see that a full page is getting reloaded, which is not true in case of AngularJS SPA. So, the next time we see each other, I will be showing you how to incorporate the AngularJS into it and delegate some control over views and routing to it. Till then in case you have any comments for me, please feel free to use the comment box below. I will be glad to help you out over here. I will continue with this series and the links for all the posts in this series will be updated in the list below.

Series Links

Part 1 Part 2 Part 3 Part 4 Part 6 Part 7 Part 8 Part 9 Part 10 Part 11

AngularJS with ASP.Net MVC (Part 4)

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 1part 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.

P1916_001

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

AngularJS with ASP.Net MVC (Part 3)

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 and part 2 in case you have not gone through that already.

I don’t want it like that …

The default template includes Bootstrap, jQuery and Modernizr as NuGet packages to the the project as soon as I added the view to it. I made it clear earlier … i don’t want it like that. I want my own or you can say different way to include these libraries. So, lets cleanup and add it differently.

Get rid of them

Open NuGet package Manager and remove bootstrap, jQuery and modernizer from the project (Select package and click Uninstall from the right side panel).

P1789_001

Open _Layout.cshtml and replace the content with the code below. Run the application and see the neat and tidy white page with your Message you entered during the previous post (Hello World! for me).

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    @RenderBody()
</body>
</html>

Using Bower

It’s not like that we don’t need jQuery or bootstrap, but we will be using bower to install them. If you are not aware of bower and how to install it, Just follow this guide on installing bower. once you have bower installed, create a file in your project name bower.json with the below contents.

{
     "name": "AngularJSwithMVC",
     "dependencies": {
     }
}

Now open the command prompt and change your directory to the project folder. Here you have to enter a few commands to add the required libraries.

bower install jquery angular ui-router bootstrap --save

bower creates a new folder named bower_components project root, which you should now include in project using solution explorer. Here is your bower.json after that command if all went well.

{
    "name": "AngularJSwithMVC",
    "dependencies": {
        "jquery": "^3.1.1",
        "angular": "^1.6.1",
        "angular-ui-router": "ui-router#^0.4.2",
        "bootstrap": "^3.3.7"
    }
}

This is the result …

Your solution / project should look something like this at the end of above steps.

P1789_002

I am not saying that using NuGet is bad but there are many other package managers out there, where bower and npm are the widely used with the latest versions continuously updated. That’s the reason we have used bower to install those libraries. Let me know which package manager you are using or want to use.

P.S. might have used npm itself in place of bower, but I am more comfortable with bower.

Please leave your comments below in case you have any questions till now on this. Your feedback is very much important to me and all the other fellow readers. I will continue on the next post where you will be able to see how to minimize the scripts and style files and include them in your webpage template.

Series Links

Part 1 Part 2 Part 4 Part 5 Part 6 Part 7 Part 8 Part 9 Part 10 Part 11