Angular JS with ASP.NET MVC – Part 3

In this post we will develop a simple page that displays the list of customers, by clicking on any record from the list, it opens up the customer page where a user can update its record. This post is a third part of Angular JS with ASP.NET application. In the last posts we developed and configured AngularJS in ASP.NET MVC app and saw different options like routing and opening views inside main application container.

Customers List Page

1

Customer Maintain Page

2

In your Angular JS – ASP.MVC project create a new folder named app and in side app create another folder customers. The reason of creating a separate app folder and then customers is to structure our solution and put all the customer related angular js controller and data adapter inside it. Controller will be used to contain the scope variables that stores the form data and Data adapter will be used to call Web API methods using angular $http object.

Step 1 – Creating Controller Data Adapter

  1. Create a new CustomerDataFactory.js file inside app/Customer folder.
  2. Add getCustomers, getCustomer, saveCustomer and deleteCustomer methods. In the code below I am using $http function of angular to call the Web API methods. I have not shown the WEB API methods in this post but you can get an idea about it calling it from Angular part.

MyApp.factory('CustomerDataFactory',

["$http",
function ($http) {
var getCustomers = function () {
return $http.get("http://localhost/WebAPIService/api/Customer");
};

var getCustomer = function (enterpriseID, customerID) {
return $http.get("http://localhost/WebAPIService/api/Customer?customerId=" + customerID);
};

 
var saveCustomer = function (customer) {
return $http.post("http://localhost/WebAPIService/api/saveCustomer", customer);
}

 
var deleteCustomer = function (customerID) {
return $http.post("http://localhost/WebAPIService/api/deleteCustomer", customer);
}

return {
getCustomers: getCustomers,
GetCustomer: getCustomer,
saveCustomer: saveCustomer,
deleteCustomer: deleteCustomer
};
}]);

Step 2 – Creating Customer Controller of Angular

  1. Create a new CustomerController.js file inside app/Customer folder

    MyApp.controller('CustomerController',

["$scope", "$window", "$routeParams", "$location", "CustomerDataFactory",
function CustomerController($scope, $window, $routeParams, $location, CustomerDataFactory) {
 

CustomerDataFactory.getCustomers()
.success(function (customers) {
$scope.customers = customers;
})
.error(function (error) {
$scope.status = 'Unable to load customers';
});
}

$scope.getCustomer = function (customer) {
$location.path("/customerMaintain/" + customer.CustomerID);
}

$scope.addCustomer = function () {
CustomerDataFactory.saveCustomer($scope.customer).success(
function (result) {
//on success
$scope.customer.CustomerID = result;
},
function (results) {
$scope.status = 'Unable to load customers';
});

}
$scope.addNewCustomer = function () {
$location.path("/customerMaintain/")
}

$scope.cancelCustomer = function () {
$window.history.back();
}
}]);

In the above code, once the controller is loaded, it will call the getCustomers method that calls the Web API method which returns all customers. On Success, it will set the collections of customers in a list.

Next, there is another method getCustomer that takes customer as an object and change the location path to customerMain which will open another page to edit customer information.

addNewCustomer does same as getCustomer in fact the form will be empty so the user can add new customer.

Step 3 – Now add these js files CustomerController.js and CustomerDataFactory.js in BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/MyApp")

.Include("~/Scripts/bootstrap.min.js")
.Include("~/Scripts/jquery-1.10.2.js")
.Include("~/Scripts/angular.min.js")
.Include("~/Scripts/angular-route.min.js")
.Include("~/Scripts/angular-ui/ui-bootstrap-tpls.min.js")
.Include("~/app/MainApp.js")
.Include("~/app/Customer/CustomerDataFactory.js")
.Include("~/app/Customer/CustomerController.js")
);

Step 4 – Add Views

  1. Create a new empty MVC Controller named as CustomerController.cs
  2. There will be two methods, Index (default) to load the Customer list page and the CustomerMaintain to load the detailed page for editing/updating customer record.

   public class CustomerController : Controller

{

// GET: Customer
public ActionResult Index()
{
return View();
}
 
public ActionResult CustomerMaintain()
{
return View();
}
}

*  When adding view for each action make sure they are partial views otherwise it won’t be open inside the main landing page

3      Complete markup for Index.cshtml that display the list of customers

         Index.cshtml
@{
Layout = null;
}

 
<div class="container-fluid">
<div class="nav">
Customers
</div>
<hr />
<p></p>
<div>
<button type="button" ng-click="addNewCustomer()" class="btn btn-default">
<i class="glyphicon glyphicon-plus"></i>
</button>
</div>
<table class="table table-striped table-hover table-responsive">
<thead>
<tr>
<th>Customer ID</th>
<th>Title </th>
<th>First Name</th>
<th>Last Name</th>
<th>Tel Number</th>
<th>Mobile Number</th>
<th>Email</th>
<th>Address 1</th>
<th>Address 2</th>
<th>City</th>
<th>PO BOX</th>
</tr>
</thead>
<tbody ng-repeat="customer in customers">
<tr ng-click="getCustomer(customer)">
<td>{{customer.CustomerID}}</td>
<td>{{customer.Title}}</td>
<td> {{customer.FirstName}}</td>
<td> {{customer.LastName}}</td>
<td> {{customer.TelNumber}}</td>
<td> {{customer.MobileNumber}}</td>
<td> {{customer.Email}}</td>
<td> {{customer.Address1}}</td>
<td> {{customer.Address2}}</td>
<td> {{customer.City}}</td>
<td> {{customer.POBox}}</td>
</tr>
</tbody>
</table>
</div>

Complete markup for CustomerMaintain.cshtml to update specific customer record or create new customer

     CustomerMaintain.cshtml
@{
Layout = null;
}
<div class="container-fluid">
<div class="nav">
Manage Customer
</div>
<br />
<form role="form" class="form-horizontal">
<div class="col-sm-3">
<button type="button" ng-click="cancelCustomer()" class="btn btn-default" ng-disabled="disableSaving">
<i class="glyphicon glyphicon-arrow-left"></i>
</button>
<button type="button" ng-click="addCustomer()" class="btn btn-primary" ng-disabled="disableSaving">
<i class="glyphicon glyphicon-floppy-save"></i>
</button>
</div>
 
<fieldset>
<legend>Customer Information</legend>
</fieldset>
<div class="form-group">
<label class="col-sm-3 control-label" for="customerID">Customer Number</label>
<div class="col-sm-9">
<input ng-model="customer.CustomerID" readonly="readonly" type="text" id="customerID" name="customerID" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="title">Title</label>
<div class="col-sm-9">
<select class="form-control" ng-model="customer.Title" name="title" id="title" required>
<option value="Company">Company</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Miss">Miss</option>
<option value="Ms">Ms</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="firstName">First Name</label>
<div class="col-sm-9">
<input ng-model="customer.FirstName" type="text" id="firstName" name="firstName" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="lastName">Last Name</label>
<div class="col-sm-9">
<input ng-model="customer.LastName" type="text" id="lastName" name="lastName" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="telNumber">Telephone Number</label>
<div class="col-sm-9">
<input ng-model="customer.TelNumber" type="text" id="telNumber" name="telNumber" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="mobileNumber">Mobile Number</label>
<div class="col-sm-9">
<input ng-model="customer.MobileNumber" type="text" id="mobileNumber" name="mobileNumber" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="email">Email</label>
<div class="col-sm-9">
<input ng-model="customer.Email" type="text" id="email" name="email" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="address1">Address 1</label>
<div class="col-sm-9">
<input ng-model="customer.Address1" type="text" id="address1" name="address1" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="address2">Address 2</label>
<div class="col-sm-9">
<input ng-model="customer.Address2" type="text" id="address2" name="address2" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="city">City</label>
<div class="col-sm-9">
<input ng-model="customer.City" type="text" id="city" name="city" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="pobox">PO Box</label>
<div class="col-sm-9">
<input ng-model="customer.POBox" type="text" id="pobox" name="pobox" class="form-control" />
</div>
</div>
</form>
</div>

Step 5 – Add routing for Customer Maintain and Customer in MyApp.js. Following is the complete markup for MyApp.js
var MyApp = angular.module('MyApp', ['ngRoute']);

MyApp.config(
 
["$routeProvider"
function ($routeProvider) {
 
$routeProvider
.when("/customer", {
templateUrl: "Customer/Index",
controller: "CustomerController"
})
.when("/customerMaintain/:CustomerID, {
templateUrl: "Customer/CustomerMaintain",
controller: "CustomerController"
})
.when("/customerMaintain/", {
templateUrl: "Customer/CustomerMaintain",
controller: "CustomerController"
})

 
}]);

That’s all, build and run the project. Hope this helps!

 

 

 

Angular JS with ASP.NET MVC – Part 2

In the first part we just configured angular JS application in ASP.NET MVC. You may have noticed that we accessed the scope variables of DemoController using $ sign. This time we will use the $route variable to route and open different views in a single page container where ng-view will be defined.

$ is a prefix that could be a property, method, variable that part of the core of AngularJS. When naming services controllers etc. it is recommended to not use $ prefix with your custom object names to avoid conflicting issues.

In this exercise we will add routing module in the MyApp.js, configure routing statements and open the ASP.NET MVC views inside a div on a single page container.

  1. First of all add the Angular Route package from NuGet Manager.
  2. Add a reference using NuGet Package Manager and search angular js route. You will see the AngularJS Route package in the Manage NuGet Packages windows. Just add it.1
  3. Now in the MyApp add ngRoute module
  4. Add the Angular-route.min.js in the BundleConfig.cs file under App_Start folder
  5. 4
  6. Edit the MyApp.js file and add ngRoute as belo
  7. This tells the angular app to use the routing module.
  8. Let’s add three actions in HomeController namely Test1, Test2 and Test3
  9. Add views to these actions, Note: all view should be partial
  10. In order to add view, just right click the Test1 function and select Add View
  11. It opens up the window where you can specify the name Test1 and check on “Create as partial view”2
  12. Once added, do these steps for ou can specify the name Test1 and check on foldera div on a single page container. d confilcting rest two methods as well namely Test2 and Test3.
  13. Now, inorder to open these view from angular we have to add a routing.
  14. In the MainApp.js we can add a routing as below3
  15. After adding this, we need to add a div on our landing page. In last post, Home/Index was our landing page (that acts as a single page container)
  16. Now add a div with ng-view attribute on it. Angular automatically opens up the page on all the containers like div, body etc where the ng-view is defined on the landing page container.5
  17. Now add, these links that opens up the page inside div6
  18. You can put any content in the partial view
  19. Let’s build and run. Click on link1 and it opens up the page inside div where ng-view is defined.7
  20. Click on second link
  21. 8
  22. At last, Click on third link 9

This covers up our second part where we used the routing feature of Angular JS. In the next post we will create factories to access database using Web API and Entity Framework as data access persistence.

AngularJS in ASP.NET MVC – Part 1

This is the first part from the series of posts I have planned for AngularJS in which I will provide an in-depth knowledge about AngularJS and how to use that in developing business applications with ASP.NET MVC, WEB API and Entity framework

In this post we will discuss about the core features of AngularJS and bootstrap with ASP .NET MVC using Visual Studio. I assume that the readers should have an in depth knowledge of ASP.NET MVC and Web APIs as I would mostly focus on the AngularJS features.

What is AngularJS

AngularJS is a web framework developed by Google tp provide responsive UI on web. It is supported for Single Page Applications where the landing page remains the same and single or multiple view can render inside it with usage of server side functions asynchronously and updating the model and control values dynamically.

You can check out the complete tutorial over here https://angularjs.org

Step by Step exercise of configuring Angular JS in ASP.NET MVC application

  1. Start Visual Studio
  2. Select ASP.NET Web Application and then MVC as project template
  3. Add references to AngularJS through NuGet
  4. Search AngularJS on the Package Manager console
  5. And then Select AngularJS Core and install

11

6. After adding AngularJS Core, add the bundle

bundles.Add(new ScriptBundle(“~/bundles/angular”)

.Include(“~/Scripts/angular.js”));

7.  Now add these bundles in the HTML head section of _Layout.cshtml

@Scripts.Render(“~/bundles/angular”)

8. Now In order to bootstrap angular JS in our MVC app we have to define the ngApp on the page body or html tag. ngApp reference to the application JS file where you can define routing, controllers etc. ngApp is a directive to auto-bootstrap an AngularJS application. Also, note that only one ngApp can be used per HTML document.

9. Let’s create two JavaScript files, one MyApp.js and the other DemoController.js

10.  Create an app folder under root in MVC project

11. Add a new JavaScript file named as MyApp.js

12. Inside MyApp.js write following snippet

var MyApp = angular.module(‘MyApp’,[]);

13. This line initialize the application level global object of angular app and a central point where you can add modules like routing, ui etc. Through this object you can add controllers, directives etc and access it globally.

14. Now specify “MyApp” to the ng-App attribute in html tag.

<html ng-app=”MyApp”>

15. Now, let’s add a DemoController.js file in your project under app folder.

16. Add following snippet in DemoController.js

MyApp.controller(‘DemoController’, [‘$scope’,

function DemoController($scope) {

$scope.Name = “ovais mehboob”;

}]);

17. Now add a div tag inside Home/Index.cshtml file and specify ng-controller as DemoController

<div ng-controller=”DemoController”>

<h1>{{Name}}</h1>

<input type=”text” ng-model=”Name” />

</div>

18. In the above code, I have specified DemoController in div tag and access scope varialbes that were defined under DemoController. Using “double curly braces” {{ }} you can access the scope variables throughout controller.

19. In order to bind the values of scope variables with input fields like textbox etc you can use ng-model and ng-bind to bind with other controls like span etc.

20. Add MyApp.js and DemoController.js inside BundleConfig.cs

bundles.Add(new ScriptBundle(“~/bundles/angular”)

.Include(“~/Scripts/jquery-1.10.2.js”,

“~/Scripts/angular.js”,

“~/app/MyApp.js”,

“~/app/DemoController.js”));

21. Let’s build and run the application

44

In the next post I will discuss about routing and rendering views inside a single page application.

Understanding OWIN by developing a custom OWIN middleware component

OWIN stands for Open Web Interface for .NET that decouples the Web Application from Web Server through an interface. In this article I will try to show some basic example of creating custom OWIN middle ware component and using it in self-host console application. The idea is to clarify the working of OWIN and what we can achieve with this new paradigm.

OWIN classifies web application into 4 parts

  1. Host
  2. Server
  3. Middleware
  4. Application
    ASP.Net MVC web application Fully OWIN compatible web applications
    Host IIS Any application Console App, Windows Service, IIS etc.
    Server IIS An application that hooks up the HTTP Listener to listen for a request.
    Middleware IHTTP Modules OWIN Middleware
    Application ASP.NET MVC 5 in IIS ASP.NET vNext, Web API 2 etc.

How is the request processed by OWIN Host?

When the request comes in to the OWIN server, the request properties like query string, path, content type, and so many others added into the IDictionary<string, object> object. This dictionary object is then sent to the request pipeline and then middleware components in the request pipeline can use this dictionary object and process accordingly.

OWIN expose following interface

System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;

Func is a new way of defining delegates in .NET framework. The first parameter denotes the input parameter and second as a return parameter. Here we have IDictionary<string,object> as input and Task as the resultant output.

When the request comes to the server, OWIN host calls the Invoke method of all the middleware components defined in order and pass the dictionary object. Each middleware component gets the complete request properties as dictionary object.

Startup.cs class is an entry point to build the request pipeline. In the Startup class, Configuration method is mandatory that takes IAppBuilder as a parameter. Using IAppBuilder you can add the OWIN based middleware and define the request pipeline. Developers can develop their own pipeline for incoming request. In IIS there are many components configured through which the request is passed through and for simple or mid-sized applications that seems to be an overkill. With OWIN based host it is quite easy to use only those OWIN extensions or middleware components that are required for your web application.

In order to elaborate, let’s create a simple OWIN middleware that logs the incoming request message into the console application and host the OWIN server in console application itself.

  1. Open Visual studio 2013 and create a new Console Application project
  2. Add OWIN NuGet references using NPM
  3. We need to add three NPM packages i.e.
    1. Microsoft.Owin – contains helper types and abstractions for simplifying the creation of OWIN components
    2. Microsoft.Owin.Host.HttpListener – OWIN server used for self-hosting
    3. Microsoft.Owin.Hosting– provides infrastructure types for hosting
  4. These libraries are part of Katana project, an implementation of OWIN by Microsoft
  5. In order to use OWIN on IIS, you can use Microsoft.Owin.Host.SystemWeb. Normally in IIS the request pipeline consists of HttpModules that are subscribes to events like BeginRequest, AuthenticateRequest etc. When you add this assembly in ASP.Net web applications you can define the OWIN based middle ware components in your Startup.cs and at runtime the Katana runtime mapped each of the middleware component to PreExecuteRequestHandler that corresponds to the PreRequestHandlerExecute event. Thus, the middleware components are invoked by the IIS integrated HTTP pipeline. This is not supported with classic HTTP pipeline.
  6. Once these references are added, we have to create a Startup.cs class and add Configuration method as below

    public void Configuration(IAppBuilder app){ }

7. Now let’s create a custom logging component to log incoming HTTP Request

      public class LoggingMiddleware

         {

              private AppFunc appFunc;

              public LoggingMiddleware(System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task> func)

           {

                 this.appFunc = func;

            }

            public async Task Invoke(IDictionary<string,object> env)

{

                  Console.WriteLine(“Request method is “+ env[“owin.RequestMethod”]);

                  var task = appFunc.Invoke(env);

}

}

8. Add this logging middleware in the configuration method using IAppBuilder use method

public void Configuration(IAppBuilder app)

{

app.Use<LoggingMiddleware>();

}


9. In the Main method of console app start the server using following WebApp.Start

Microsoft.Owin.Hosting.WebApp.Start<Startup>(http://localhost:12345&#8243;);

Console.ReadLine();


Following is a complete code

     

public class Startup

{

public void Configuration(IAppBuilder app)

{

app.Use<LoggingMiddleware>();

}

}

public class LoggingMiddleware

{

private AppFunc appFunc;

public LoggingMiddleware(System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task> func)

{

this.appFunc = func;

}

public async Task Invoke(IDictionary<string,object> env)

{

Console.WriteLine(“Request method is “+ env[“owin.RequestMethod”]);

var task = appFunc.Invoke(env);

}

}

class Program

{

static void Main()

{

Microsoft.Owin.Hosting.WebApp.Start<Startup>(http://localhost:12345&#8243;);

Console.ReadLine();

}

}

}

10. Now run the application and access the URL http://localhost:5555

11. You will see the logging on your console app.

Reviewed book “Bootstrap for ASP.NET MVC” by Pieter van der Westhuizen

I have gotten this opportunity to review the book named “Bootstrap for ASP.NET MVC” from Packt (UK based publishing company specializing in focused IT books).

Following is a review I made for this book

This book is a perfect guide to learn about using Bootstrap in ASP.NET MVC applications. Pieter does not only provided the basic information about incorporating Bootstrap in ASP.NET MVC but for almost each topic there are steps provided with code snippets that helps the reader to perform hands-on on the fly.

 

Follow

Get every new post delivered to your Inbox.

Join 86 other followers

%d bloggers like this: