AngularJS with ASP.Net MVC (Part 8)

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. In the previous post we have replaced the angular-route with ui-router and the application is behaving same. You can read those posts part 1part 2part 3part 4part 5part 6 and part 7 in case you have not gone through that already. Let’s move to next step where we will be demonstrating the core feature of a ui-router’s state.

URL vs State

With angular-route, we are bound to the url, i.e. each resource is linked to its url. whereas in case of ui-router resources are liked to state which intern gets linked to optional url. There are scenarios in large applications, where we would like to keep the url same, but change the content based on some conditions. In simple words content is based on the state of the application in place of URL in the navigation bar.

View vs Views

angular-route can only show a single view at a time and view nesting is not supported. Whereas in case of ui-router, we can have multiple view in a single template, which also can be nested inside of other.

for example, we can define separate templates for header, footer, navigation and content on the same page. See the images below for more clarity.

P2163_001

Let’s be Practical

We have seen in part 7 how the states are defined. Here today we will see how we can have multiple / nested views in a given template. In the previous post, we have defined state as below.

state('home', {
    url: '/',
    templateUrl: 'Home/Home'
})

Let’s extend this for having multiple views per state. To do so, modify your page1 state as below.

state('page1', {
                    url: '/Page1',
                    views: {
                        '@': {
                            templateUrl: '/Home/Page1'
                        },
                        'left@page1': {
                            templateUrl: 'Home/Page1Left'
                        },
                        'right@page1': {
                            templateUrl: 'Home/Page1Right'
                        }
                    }
                })

Notice the views object, which replaced the templateUrl. It contains a few fields containing ‘@’. These fields defines the target for the view template. You can read that notation as <viewName>’@'<stateName>. In case of the first field, where viewName and stateName are missing means that it should target the ui-view which has no name and is not defined by any state. Do you know which view placeholder we are talking here. Yes, you are right, the one which we have declared in Index.cshtml.

Where are the other views?

Continue to modify the files as per the snippets below and then we will talk. Open your HomeController.cs and add to new actions methods as shown in the snippet below.

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

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

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

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

Add the corresponding views for those action methods with the content as shown below

// Page1Left.cshtml
<h2>Left</h2>
// Page1Right.cshtml
<h2>Right</h2>

Modify the Page1.cshtml as per the snippet below.

<h1>Page 1</h1>
<div class="row">
    <div class="col-md-6 col-sm-6" ui-view="left"></div>
    <div class="col-md-6 col-sm-6" ui-view="right"></div>
</div>

Correct! you got it. In page1.cshtml, there you can see that 2 more ui-view’s are defined. Page1.cshtml is loaded by the page1 state as the base so, left and right views are state defined views and that’s why the routing configuration we have mentioned as left@page1 and right@page1.

The Output

P2163_002

If you navigate to Page1, you will see the above output. Here, index.cshtml loads the page1.cshml and page1.cshtml loads page1left.cshtml with page1right.cshtml. This demonstrates the view nesting with multiple views.

Why MVC View rather static HTML?

Static HTML pages are good in case where we don’t want to change the contents of the html template at run time. But in a scenario where we would like to change the contents of the template MVC view are very useful. Along with that there might be scenarios where we would like to show different templates itself based on different user roles and authorizations. We can control a lot more with MVC views as compared to the static HTML. The possibilities are unlimited.

Truly speaking, this is the ultimate reason, why anyone would want to use AngularJS with ASP.Net MVC. In the next post we will see more aspects of ASP.Net MVC getting utilized in this application rather just getting template view from it.

Video demonstrating the ui-router advance usage
description: Series: AngularJs with ASP.Net MVC In this video we are going to see the advanced usage of ui-router like nested views and multiple views as sub views. references are taken from blog post series: https://www.mindzgrouptech.net/8ujs
duration: 00:06:30
views: 309
by: MindzGroupTech
source: YouTube
Get this plugin here.

In case you have any questions or concerns, please do leave your comments below. I will try to answer them as soon as possible. Your feedback will help me improve the contents. Have a nice day.

Series Links

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

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.

Navigation Demo
Navigation Demo

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.

This video shows the how to include ui-router in MVC
description: Series: AngularJs with ASP.Net MVC In this video we are going to replace the angular-route with angular-ui-router. references are taken from blog post series: https://www.mindzgrouptech.net/7jxl
duration: 00:06:15
views: 477
by: MindzGroupTech
source: YouTube
Get this plugin here.

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 …

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.

This video shows the including of AngularJS in MVC
description: Series: AngularJs with ASP.Net MVC In this video we will be including angular on top of ASP.Net MVC application created during the previous video. references are taken from blog post series: https://www.mindzgrouptech.net/urpd
duration: 00:18:53
views: 531
by: MindzGroupTech
source: YouTube
Get this plugin here.

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

In this video we are building the complete MVC application with bootstrap
description: Series: AngularJs with ASP.Net MVC In this video we will be creating a minimal ASP.Net MVC application so that we can use it for adding the angular dependencies later during the session. references are taken from blog post series: https://www.mindzgrouptech.net/22d0
duration: 00:10:40
views: 725
by: MindzGroupTech
source: YouTube
Get this plugin here.

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.

In this video we are building the complete MVC application with optimization
description: Series: AngularJs with ASP.Net MVC In this video we will be creating a minimal ASP.Net MVC application so that we can use it for adding the angular dependencies later during the session. references are taken from blog post series: https://www.mindzgrouptech.net/22d0
duration: 00:10:40
views: 725
by: MindzGroupTech
source: YouTube
Get this plugin here.

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