Bipin Joshi, Author at CodeGuru https://www.codeguru.com/author/bipin-joshi/ Thu, 06 Jan 2022 17:49:34 +0000 en-US hourly 1 https://wordpress.org/?v=6.3.2 Understanding Routing in ASP.NET Core MVC https://www.codeguru.com/dotnet/understanding-routing-in-asp-net-core-mvc/ Mon, 12 Jun 2017 07:15:00 +0000 https://www.codeguru.com/uncategorized/understanding-routing-in-asp-net-core-mvc/ In ASP.NET Core MVC, a request URL is mapped to a controller’s action. This mapping happens through the routing middleware and you can do good amount of customization. There are two ways of adding routing information to your application: conventional routing and attribute routing. This article introduces you with both of these approaches with the […]

The post Understanding Routing in ASP.NET Core MVC appeared first on CodeGuru.

]]>
In ASP.NET Core MVC, a request URL is mapped to a controller’s action. This mapping happens through the routing middleware and you can do good amount of customization. There are two ways of adding routing information to your application: conventional routing and attribute routing. This article introduces you with both of these approaches with the help of an example.

To understand how conventional and attribute routing works, you will develop a simple Web application, as shown in Figure 1.

A routing form
Figure 1: A routing form

The Web page shown in Figure 1 displays a list of orders from the Orders table of the Northwind database. The launching page follows the default routing pattern: /controller/action. Every order row has Show Details links. This link, however, renders URLs of the following form:

/OrderHistory/CustomerID/order_year/order_month/order_day/OrderID

As you can see, this URL doesn’t follow the default routing pattern of ASP.NET Core MVC. These URLs are handled by a custom route that we specify in the application. Clicking the Show Details link takes the user to another page, where order details such as OrderDate, ShipDate, and ShipAddress are displayed (see Figure 2).

Details for a customer's order
Figure 2: Details for a customer’s order

Let’s develop this example and also discuss routing as we progress. The example uses Entity Framework Core for database access. Although we will discuss the EF Core code briefly, detailed discussion of EF Core is beyond the scope of this article. It is assumed that you are familiar with the basics of working with EF Core.

Okay. Create a new ASP.NET Core Web Application using Visual Studio. Because we want to use EF Core, add the NuGet package: Microsoft.EntityFrameworkCore.SqlServer. To add this package, right-click the Dependencies folder and select the “Manage NuGet Packages…” shortcut menu option. Then, search for the above-mentioned package and install it for your project.

Managing NuGet packages
Figure 3: Managing NuGet packages

Then, add a Models folder to your project root and add two class files into it: NorthwindDbContext.cs and Order.cs. Open the Order.cs file and add the following class definition to it.

[Table("Orders")]
public class Order
{
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   [Required]
   public int OrderID { get; set; }
   [Required]
   public string CustomerID { get; set; }
   [Required]
   public DateTime OrderDate { get; set; }
   [Required]
   public string ShipName { get; set; }
   [Required]
   public string ShipAddress { get; set; }
   [Required]
   public string ShipCity { get; set; }
   [Required]
   public string ShipCountry { get; set; }
}

The Order class contains seven properties, namely: OrderID, CustomerID, OrderDate, ShipName, ShipAddress, ShipCity, and ShipCountry. The Order class is mapped to the Orders table by using the [Table] attribute.

Also, open the NorthwindDbContext class file and add the following code in it:

public class NorthwindDbContext : DbContext
{
   public DbSet<Order> Orders { get; set; }

   protected override void OnConfiguring
      (DbContextOptionsBuilder optionsBuilder)
   {
      optionsBuilder.UseSqlServer("data source=.;
         initial catalog = northwind;
         integrated security = true");
   }
}

The NorthwindDbContext inherits from the DbContext class. Inside, it declares Orders DbSet. The OnConfiguring() method is used to configure the database connection string. Here, for the sake of simplicity, we pass a hard-coded connection string to the UseSqlServer() method. You also could have used dependency injection. Make sure to change the database connection string as per your setup.

Conventional Routing

Now, open the Startup.cs file and go to the Configure() method. The Configure() method is used to configure middleware. Somewhere inside this method, you will find the following code:

app.UseMvc(routes =>
{
   routes.MapRoute(
      name: "default",
      template: "{controller=Home}/
         {action=Index}/{id?}");

});

The preceding code calls the UseMvc() method and also configures the default routing. Notice the MapRoute() call carefully. It defines a route named default and also specifies the URL template. The URL template consists of three parameters: {controller}, {action}, and {id}. The default value for the controller is Home, the default value foe action is Index, and the id is marked as an optional parameter.

If all you need is this default route, you also can use the following line of code to accomplish the same task:

app.UseMvcWithDefaultRoute();

This is the conventional way of defining routes and you can add your custom route definitions easily. Let’s add another route that meets our requirement:

app.UseMvc(routes =>
{
   routes.MapRoute(
      name: "OrderRoute",
      template: "OrderHistory/{customerid}/{year}/
         {month}/{day}/{orderid}",
      defaults: new { controller = "Order",
         action = "ShowOrderDetails" });

   routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");

});

Notice the code marked in the bold letters. We added another route, named OrderRoute. This time, the URL template begins with static segment—OrderHistory— that won’t change with each URL. Further, the URL template contains five parameters: {customerid}/{year}/{month}/{day}/{orderid}. The default parameter sets the default controller to Order and the default action to ShowOrderDetails.

Now that you have the desired route definition in place, it’s time to create the HomeController and OrderController.

Add HomeController and OrderController to the Controllers folder by using the Add New Item dialog. The HomeController’s Index() action is shown below:

public IActionResult Index()
{
   using (NorthwindDbContext db = new
      NorthwindDbContext())
   {
      return View(db.Orders.ToList());
   }
}

The Index() action simply passes a list of all the orders to the Index view for the sake of displaying in a table.

Next, add an Index view under Views > Home folder and write the following markup in it.

@model List<RoutingInAspNetCore.Models.Order>

<html>
   <head>
      <title>List of Orders</title>
   </head>
   <body>
      <h2>List of Orders</h2>

      <table cellpadding="10" border="1">
         <tr>
            <th>Order ID</th>
            <th>Customer ID</th>
            <th>Action</th>
         </tr>
         @foreach (var item in Model)
         {
            <tr>
               <td>@item.OrderID</td>
               <td>@item.CustomerID</td>
               <td>@Html.RouteLink("Show Details",
                     "OrderRoute",new {
                  customerid=item.CustomerID,
                  year=item.OrderDate.Year,
                  month=item.OrderDate.Month,
                  day=item.OrderDate.Day,
                  orderid=item.OrderID }) </td>
            </tr>
         }
      </table>
   </body>
</html>

The Index view renders a table that lists OrderID and CustomerID of all the orders. Each order row has a link that points to the order details page. Notice how the link is rendered. We use the Html.RouteLink() helper to render this hyperlink. The first parameter of RouteLink() is the text of the hyperlink (Show Details, in this case). The second parameter is the name of the route as specified in the route definition (OrderRoute, in this case). The third parameter is an anonymous object holding all the values for the route parameters. In this case, there are five parameters: customerid, year, month, day, and orderid. The values of these parameters are picked from the corresponding Order object.

Okay. Now, open OrderController and add the ShowOrderDetails() action, as shown below:

public IActionResult ShowOrderDetails(string customerid,
   int orderid,int year,int month,int day)
{
   ViewBag.Message = $"Order #{orderid} for customer
      {customerid} on {day}/{month}/{year}";

   using (NorthwindDbContext db = new NorthwindDbContext())
   {
      Order order = db.Orders.Find(orderid);
      return View(order);
   }
}

The ShowOrderDetails() action takes five parameters corresponding to the route parameters. Inside, a message is stored in the ViewBag that indicates the OrderID, CustomerID, and OrderDate of the given order. Moreover, the code fetches the Order object from the Orders DbSet matching the OrderID. The Order object then is passed to the ShowOrderDetails view.

Now, add the ShowOrderDetails view to the Views > Order folder and add the following markup to it.

@model RoutingInAspNetCore.Models.Order

<html>
   <head>
      <title>Orders Details</title>
   </head>
   <body>
      <h2>@ViewBag.Message</h2>
      <h2>Order Details</h2>
      @Html.DisplayForModel()
   </body>
</html>

The ShowOrderDetails view simply outputs the Message ViewBag variable. All the properties of Order model object are outputted by using the DisplayForModel() helper.

This completes the application. Run the application, navigate to /Home/Index, and see whether the order listing is displayed. Then, click the Show Details link for an order and check whether order details are being shown as expected.

Attribute Routing

The previous example uses conventional routing. Now, let’s use attribute routing to accomplish the same task.

First of all, comment out the existing UseMvc() call so that conventional routing is no longer enabled. Then, add the following call at that place:

app.UseMvc();

As you can see, the UseMvc() call no longer contains routing information. Then, open HomeController and add the [Route] attribute on top of it as shown next:

[Route("[controller]/[action]/{id?}")]
public class HomeController : Controller
{
   ....
}

Now, the HomeController has been decorated with the [Route] attribute. The [Route] attribute defines the URL pattern using special tokens: [controller] and [action]. An optional id parameter also has been specified. This is equivalent to {controller}/{action}/{id} of the conventional routing.

If you want to set HomeController as the default controller and Index() as the default action, you would have done this:

public class HomeController : Controller
{
   [Route("")]
   [Route("Home")]
   [Route("Home/Index")]
   public IActionResult Index()
   {
      ....
   }
}

Here, the [Route] attribute has been added on top of the Index() action and sets the defaults as needed.

Okay. Then, open OrderController and add the [Route] attribute, as shown below:

[Route("OrderHistory/{customerid}/{year}/{month}/{day}/
   {orderid}",Name ="OrderRoute")]
public IActionResult ShowOrderDetails(string customerid,
   int orderid,int year,int month,int day)
{
   ....
}

Here, you added the [Route] attribute on top of the ShowOrderDetails() action. The [Route] attribute contains the same URL pattern as before. The name of the route also is specified by setting the Name property.

If you run the application, it should work as expected.

Route Constraints

You also can put constraints on the route parameters. Route constraints allow you to ensure that a route value meets certain criteria. For example, you may want to ensure that the CustomerID route value is a string with five characters. Or, the month value is between 1 and 12. You can add route constraints to both conventional routes as well as attribute routes. Let’s see how.

Consider the following piece of code:

routes.MapRoute(
   name: "OrderRoute",
   template: "OrderHistory/{customerid:alpha:length(5)}/
      {year:int:length(4)}/{month:int:range(1,12)}/
      {day:int:range(1,31)}/{orderid:int}",
   defaults: new { controller = "Order",
      action = "ShowOrderDetails" });
[Route("{customerid:alpha:length(5)}/{year:int:length(4)}/
   {month:int:range(1,12)}/{day:int:range(1,31)}/
   {orderid:int}",Name ="OrderRoute")]

The preceding code shows how route constraints can be applied. The above example uses the following constraints:

  • The alpha constraint is used to ensure that the value contains only alphabetical characters.
  • The length(n) constraint is used to ensure that a value must have a length equal to the specified number.
  • The int constraint is used to ensure that the value is an integer.
  • The range(a,b) constraint is used to ensure that a value falls within certain a minimum and maximum range.

There are many more constraints available. A parameter can have more than one constraint attached with it. You can read more about route constraints here.

After adding these constraints, run the application, navigate to the order details page, and then change the CustomerID in the browser’s address bar to some string more than 5 characters. Or, try changing the month to some number higher than 12. You will find that the request is rejected and doesn’t reach the ShowOrderDetails() action.

Conclusion

This article examined how conventional and attribute routing of ASP.NET Core MVC work. You may learn more about routing here. The complete source code of the example we discussed in this article is also available for download.

The post Understanding Routing in ASP.NET Core MVC appeared first on CodeGuru.

]]>
Creating a Web API in ASP.NET Core https://www.codeguru.com/dotnet/creating-a-web-api-in-asp-net-core/ Mon, 15 May 2017 07:15:00 +0000 https://www.codeguru.com/uncategorized/creating-a-web-api-in-asp-net-core/ RESTful services are quite common and popular these days. If you ever developed modern service-based applications using ASP.NET Web Forms and ASP.NET MVC, chances are you used a Web API to create REST services. No wonder ASP.NET Core also allows you to create a Web API. This article discusses how a Web API service can […]

The post Creating a Web API in ASP.NET Core appeared first on CodeGuru.

]]>
RESTful services are quite common and popular these days. If you ever developed modern service-based applications using ASP.NET Web Forms and ASP.NET MVC, chances are you used a Web API to create REST services. No wonder ASP.NET Core also allows you to create a Web API. This article discusses how a Web API service can be created in ASP.NET Core. It then shows how the created service can be invoked from JavaScript code.

Creating the Employee service

Let’s create a Web API service that performs CRUD (Create, Read, Update, and Delete) operations on the Employees table of the Northwind database.

To begin, create a new ASP.NET Core Web application using Visual Studio 2017 (see Figure 1).

Creating a new ASP.NET Core Web application
Figure 1: Creating a new ASP.NET Core Web application

Pick Web API as the project template in the next dialog, shown in Figure 2.

Choosing the project template
Figure 2: Choosing the project template

This way, you will get the default configuration and Web API controller that you can modify to suit your needs.

When you create the project, open ValuesController.cs from the Controllers folder. You should see something like this:

namespace WebAPIInAspNetCore.Controllers
{
   [Route("api/[controller]")]
   public class ValuesController : Controller
   {
      [HttpGet]
      public IEnumerable<string> Get()
      {
         return new string[] { "value1", "value2" };
      }

      [HttpGet("{id}")]
      public string Get(int id)
      {
         return "value";
      }
      ....
      ....
}

Notice that the ValuesController class inherits from the Controller base class. This is different as compared to ASP.NET. In ASP.NET, the Web API controller inherits from the ApiController base class. In ASP.NET Core, the Web API has been merged with MVC; therefore, both the controllers—the MVC controller as well as the Web API controllers—inherit from the Controller base class.

Because Web API is now just another controller, you can have as many actions you want. Of course, to create a REST style service, you still need to have those standard Get(), Post(), Put(), and Delete() actions as before. You can define the HTTP verb and action mapping on top of an action by using attributes such as [HttpGet], [HttpPost], [HttpPut], and [HttpDelete]. This is different than before, where HTTP verbs were automatically mapped with the actions by default. The ValuesController class also has a [Route] attribute that decides how the service will be accessed. By default, the service URL takes the form /api/values, but you can change the route as needed.

Okay. Rename the ValuesController (both the class and the .cs files) to EmployeeController and save the file. You will revisit EmployeeController after creating the Entity Framework Core model required by the application.

Next, you need to add Entity Framework Core to your project. To do so, right-click the Dependencies folder in the Solution Explorer, and select the Manage NuGet Packages option. Then, add the EntityFrameworkCore.SqlServer NuGet package. After doing this step, you should see the required packages added to your project (see Figure 3).

Adding the EntityFrameworkCore.SqlServer NuGet package
Figure 3: Adding the EntityFrameworkCore.SqlServer NuGet package

Then, open the Startup class and add EF Core to the services collection. The following code shows how this is done:

public void ConfigureServices(IServiceCollection services)
{
   // Add framework services.
   services.AddMvc();
   services.AddEntityFrameworkSqlServer();
}

ConfigureServices() calls AddEntityFrameworkSqlServer() to add EF Core to the list of services. Although we are not configuring the DbContext here for DI, you could have done so if needed. For the sake of simplicity, we will specify the connection string in the DbContext class itself.

Also, modify the Configure() method to set up the default MVC route as shown below:

public void Configure(IApplicationBuilder app,
   IHostingEnvironment env, ILoggerFactory loggerFactory)
{
   loggerFactory.AddConsole(Configuration.GetSection
      ("Logging"));
   loggerFactory.AddDebug();
   app.UseMvcWithDefaultRoute();
}

Here, we call the UseMvcWithDefaultRoute() method to configure the default route (/controller/action/id) for MVC requests. We do this because later we will develop a JavaScript client that invokes the Web API. And, we will need an MVC controller.

Now, you can create the EF Core model needed by the application. To do so, add a Models folder (you could have placed these classes in some other folder, also) and add two classes to it—Employee and NorthwindDbContext. The following code shows what Employee class looks like.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace WebAPIInAspNetCore.Models
{
   [Table("Employees")]
   public class Employee
   {
      [DatabaseGenerated(DatabaseGeneratedOption
         .Identity)]
      [Required]
      public int EmployeeID { get; set; }
      [Required]
      public string FirstName { get; set; }
      [Required]
      public string LastName { get; set; }
      [Required]
      public string City { get; set; }
   }
}

The Employee class is mapped to the Employees table using the [Table] data annotation attribute. It has four properties: EmployeeID, FirstName, LastName, and City. The EmployeeID property also is marked using the [DatabaseGenerated] attribute because it’s an identity column.

The NorthwindDbContext class is shown next.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore;


namespace WebAPIInAspNetCore.Models
{
   public class NorthwindDbContext : DbContext
   {
      public DbSet<Employee> Employees { get; set; }

      protected override void OnConfiguring
      (DbContextOptionsBuilder optionsBuilder)
      {
         optionsBuilder.UseSqlServer("data
            source=.;initial catalog =
            northwind;integrated security = true");
      }
   }
}

The NorthwindDbContext class inherits from the DbContext class. It defines Employees DbSet. The connection string to the Northwind database is specified by using the OnConfiguring() method. Make sure to change the database connection string as per your setup.

Okay. So far, so good. Now, open the EmployeeController and write the following code in it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

using WebAPIInAspNetCore.Models;
using Microsoft.EntityFrameworkCore;

namespace WebAPIInAspNetCore.Controllers
{
   [Route("api/[controller]")]
   public class EmployeeController : Controller
   {

      [HttpGet]
      public List<Employee> Get()
      {
         using (NorthwindDbContext db = new
            NorthwindDbContext())
         {
            return db.Employees.ToList();
         }
      }

      [HttpGet("{id}")]
      public Employee Get(int id)
      {
         using (NorthwindDbContext db = new
            NorthwindDbContext())
         {
            return db.Employees.Find(id);
         }
      }

      [HttpPost]
      public IActionResult Post([FromBody]Employee obj)
      {
         using (NorthwindDbContext db = new NorthwindDbContext())
         {
            db.Employees.Add(obj);
            db.SaveChanges();
            return new ObjectResult("Employee added successfully!");
         }
      }

      [HttpPut("{id}")]
      public IActionResult Put(int id, [FromBody]Employee obj)
      {
         using (NorthwindDbContext db = new NorthwindDbContext())
        {
            db.Entry<Employee>(obj).State = EntityState.Modified;
            db.SaveChanges();
            return new ObjectResult("Employee modified successfully!");
         }
      }

      [HttpDelete("{id}")]
      public IActionResult Delete(int id)
      {
         using (NorthwindDbContext db = new NorthwindDbContext())
         {

            db.Employees.Remove(db.Employees.Find(id));
            db.SaveChanges();
            return new ObjectResult("Employee deleted successfully!");
         }
      }
   }
}

The EmployeeController consists of five actions: Get(), Get(id), Post(), Put(), and Delete(). These actions are discussed next.

The Get() action returns a List of Employee objects. Inside, the code instantiates the NorthwindDbContext and returns all the entities from the Employees DbSet. The Get(id) action accepts an EmployeeID and returns just that Employee as its return value.

The Post() action receives an Employee object as its parameter. This is the new employee to be added to the database. Inside, it adds the Employee to the Employees DbSet by using the Add() method. The SaveChanges() method is called to save the changes to the database. Notice that the obj parameter is decorated with the [FormBody] attribute. This is necessary for model binding with JSON data to work as expected. The Post() returns a success message wrapped in ObjectResult to the caller.

The Put() method accepts two parameters: EmployeeID and Employee object. Inside, the State property is set to EmployeeState.Modified. This way, the entity is marked as modified. The SaveChanges() method attempts to save the changes to the database. The Put() method also returns a success message as before.

The Delete() action accepts an EmployeeID to be deleted. It then looks for that Employee in the Employees DbSet. This is done by using the Find() method. The existing Employee returned by Find() is removed from the DbSet by using the Remove() method. The SaveChanges() action is called to save the changes to the database. A success message is then returned to the caller.

Now, run the application by pressing F5. If all goes well, you should see the JSON data returned from the Get() action. Figure 4 shows how the JSON data is displayed in Firefox.

JSON data has been returned from the Get() action
Figure 4: JSON data has been returned from the Get() action

Creating a Client by Using jQuery Ajax

Now that your Employee service is ready, let’s consume it by building a jQuery client. Right-click the Controllers folder and select Add > New Item from the shortcut menu. Using the Add New Item dialog, add an MVC controller—HomeController (see Figure 5).

Building a jQuery client
Figure 5: Building a jQuery client

The controller contains the Index() action. We don’t need to add any code to Index() because all our code will be in the Index view. Index() simply returns the view.

Then, add a subfolder under Views and name it Home. Next, add an Index viewer to the the Views > Home folder. This can be done by using the Add New Item dialog as before (see Figure 6).

Adding an Index viewer to the the Views > Home folder
Figure 6: Adding an Index viewer to the the Views > Home folder

Then, add Scripts folder under wwwroot folder and place the jQuery library there. If you want, you also can reference jQuery from CDN.

Now, you need to design a form that looks like what you see in Figure 7:

Designing the form
Figure 7: Designing the form

The preceding Web page consists of a form that allows you to add, modify, and remove employees. When the page loads in the browser, the EmployeeID dropdownlist displays a list of existing EmployeeIDs. Upon selecting an EmployeeID, details of that Employee are fetched from the database and displayed in the first name, last name, and city textboxes. You then can modify the details and click the Update button to save them to the database. You can click the Delete button if you want to delete the selected employee. To add a new employee, simply enter a new first name, last name, and city values and click the Insert button (EmployeeID is an identity column and therefore need not be entered from the page). The success message returned from the respective Web API actions is displayed in a <div> element below the table.

The following markup shows the HTML form behind this page.

<h1>Employee Manager</h1>
<form>
   <table border="1" cellpadding="10">
      <tr>
         <td>Employee ID :</td>
            <td>
               <select id="employeeid"></select>
         </td>
      </tr>
      <tr>
         <td>First Name :</td>
            <td><input id="firstname"
                       type="text" /></td>
      </tr>
      <tr>
         <td>Last Name :</td>
         <td><input id="lastname"
                    type="text" /></td>
      </tr>
      <tr>
         <td>City :</td>
         <td><input id="city"
                    type="text" /></td>
      </tr>
      <tr>
         <td colspan="2">
            <input type="button" id="insert"
                   value="Insert" />
            <input type="button" id="update"
                   value="Update" />
            <input type="button" id="delete"
                   value="Delete" />
         </td>
      </tr>
   </table>
   <br />
   <div id="msg"></div>
</form>

The <form> consists of a <select> element, three textboxes, and three buttons. Make sure to use the same IDs for the elements because later you will use them in the jQuery code. After adding the form markup, go in the <head> section and reference the jQuery library by using the <script> tag.

<script src="~/Scripts/jquery-3.1.1.min.js"></script>

Now, we need to write some jQuery code that invokes the Web API by making requests with appropriate HTTP verbs. Add an empty <script> block below the previous script reference and write the code discussed in the following sections.

Filling the dropdownlist with EmployeeIDs

$(document).ready(function () {
   var options = {};
   options.url = "/api/employee";
   options.type = "GET";
   options.dataType = "json";
   options.success = function (data) {
      data.forEach(function (element) {
         $("#employeeid").append("<option>"
            + element.employeeID + "</option>");
      });
   };
   options.error = function () {
      $("#msg").html("Error while calling the Web API!");
   };
   $.ajax(options);
}

The EmployeeID dropdownlist is populated in the ready() callback. The preceding code makes an Ajax request using the $.ajax() method of jQuery. Notice how the URL, type, and dataType properties of the options object are specified. Because we want to invoke the Get() action, the URL points to the Web API end point: /api/employee. The HTTP verb used is GET and the response data type is set to json. The success function simply fills the dropdownlist (the <select> element) with a series of elements, each wrapping an EmployeeID. The error function displays an error message in case something goes wrong while calling the Web API. Once the options object is configured, $.ajax() of jQuery is called by passing the options object to it. Doing so will initiate an Ajax request to the Web API based on the specified configuration.

Displaying the Details of a Selected Employee

$("#employeeid").change(function () {
   var options = {};
   options.url = "/api/employee/" +
      $("#employeeid").val();
   options.type = "GET";
   options.dataType = "json";
   options.success = function (data) {
      $("#firstname").val(data.firstName);
      $("#lastname").val(data.lastName);
      $("#city").val(data.city);
   };
   options.error = function () {
      $("#msg").html("Error while calling the Web API!");
   };
   $.ajax(options);
});

When a user selects an EmployeeID from the dropdownlist, details of that Employee are to be displayed in the other textboxes. Therefore, we use the change() method to wire an event handler to the change event of the dropdownlist. The code shown above is quite similar to the previous one in that it uses the GET verb. However, it appends the EmployeeID whose details are to be fetched to the URL. The success function fills the three textboxes with firstName, lastName, and city. Notice that the property names are automatically converted to use camel casing. This way, client-side code can use JavaScript ways of naming members, whereas server-side code can continue to use C# naming conventions.

Adding a New Employee

$("#insert").click(function () {
   var options = {};
   options.url = "/api/employee";
   options.type = "POST";

   var obj = {};
   obj.firstName = $("#firstname").val();
   obj.lastName = $("#lastname").val();
   obj.city = $("#city").val();

   options.data = JSON.stringify(obj);
   options.contentType = "application/json";
   options.dataType = "html";

   options.success = function (msg) {
      $("#msg").html(msg);
   };
   options.error = function () {
      $("#msg").html("Error while calling the Web API!");
   };
   $.ajax(options);
});

The code to add a new Employee goes inside the click event handler of the insert button. The above code uses the POST verb to invoke the Employee Web API. Moreover, it sets data, dataType, and contentType properties. The data property is set to the stringified version of the new Employee object. Notice that this new object also uses camel casing when setting the properties. The dataType property is set to HTML because our Post() action returns a plain string. The contentType property indicates the request’s data type—JSON, in this case. The success function simply displays the message returned by the Post() action into the msg <div> element.

Modifying an Existing Employee

$("#update").click(function () {
   var options = {};
   options.url = "/api/employee/"
      + $("#employeeid").val();
   options.type = "PUT";

   var obj = {};
   obj.employeeID = $("#employeeid").val();
   obj.firstName = $("#firstname").val();
   obj.lastName = $("#lastname").val();
   obj.city = $("#city").val();

   options.data = JSON.stringify(obj);
   options.contentType = "application/json";
   options.dataType = "html";
   options.success = function (msg) {
      $("#msg").html(msg);
   };
   options.error = function () {
      $("#msg").html("Error while calling the Web API!");
   };
   $.ajax(options);
});

The code that updates employee details goes in the click event handler of the update button. Most of the previous code is similar to the code you wrote in the insert click event handler, except that the EmployeeID being modified is appended to the URL, and the HTTP verb used is PUT.

Deleting an Employee

$("#delete").click(function () {
   var options = {};
   options.url = "/api/employee/"
      + $("#employeeid").val();
   options.type = "DELETE";
   options.dataType = "html";
   options.success = function (msg) {
      $("#msg").html(msg);
   ;
   options.error = function () {
      $("#msg").html("Error while calling the Web API!");
   };
   $.ajax(options);
});

The code that deletes an Employee goes in the click event handler of the delete button. The above code should look familiar to you because it follows the same outline as the other event handlers. This time, the HTTP verb used is DELETE and the EmployeeID to be deleted is appended to the URL.

This completes the client application. Run the application, navigate to /Home/Index, and test the CRUD operations.

Using DI to Inject DbContext into the Web API Controller

In the example you just developed, you instantiated NorthwindDbContext yourself in the EmployeeController. You also can put the DI features of ASP.NET Core to use for that purpose. Let’s see how.

Open the appsettings.json file and store the database connection in it, as shown below:

{
   "Logging": {
      "IncludeScopes": false,
      "LogLevel": {
         "Default": "Warning"
      }
   },
   "ConnectionStrings": {
      "DefaultConnection": "Server=.;
         initial catalog=Northwind;
         integrated security=true;
         MultipleActiveResultSets=true"
   }
}

As you can see, the ConnectionString key stores the Northwind connection string with the name DefaultConnection. Make sure to change the connection string to suit your setup.

Then, open the Startup class and import these two namespaces:

using WebAPIInAspNetCore.Models;
using Microsoft.EntityFrameworkCore;

Here, we imported the Models namespace because our DbContext and entity classes reside in that namespace. We also imported Microsoft.EntityFrameworkCore because we want to use certain extension methods from this namespace.

Then, add the following code to the ConfigureServices() method.

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   services.AddEntityFrameworkSqlServer();
   services.AddDbContext<NorthwindDbContext>(
   options => options.UseSqlServer(
      Configuration.GetConnectionString("DefaultConnection")));

}

The preceding code registers the NorthwindDbContext with the DI framework. We also specify the connection string by using the UseSqlServer() extension method. Because you are specifying the connection string here, you can remove now OnConfiguring() from the NorthwindDbContext class. You also need to make one more addition in the NorthwindDbContext class. Add a public constructor, as shown below:

public NorthwindDbContext(DbContextOptions
   options) : base(options)
{

}

This constructor accepts a DbContextOptions object and passes it to the DbContext base class.

Now, open the EmployeeController class and modify it as shown below:

[Route("api/[controller]")]
public class EmployeeController : Controller
{

   private NorthwindDbContext db;

   public EmployeeController(NorthwindDbContext db)
   {
      this.db = db;
   }
   ....
}

The code declares a private NorthwindDbContext variable to hold the reference to the injected DbContext. The public constructor accepts the NorthwindDbContext. Once we grab the DbContext, you can use it in all the actions. As an example, the following code uses the injected DbContext in the Get() action.

[HttpGet]
public List<Employee> Get()
{
   return db.Employees.ToList();
}

The complete source code of this example is available with this article’s code download.

The post Creating a Web API in ASP.NET Core appeared first on CodeGuru.

]]>
Performing Database Operations using Entity Framework Core and ASP.NET Core https://www.codeguru.com/dotnet/performing-database-operations-using-entity-framework-core-and-asp-net-core/ Fri, 08 Jul 2016 07:15:00 +0000 https://www.codeguru.com/uncategorized/performing-database-operations-using-entity-framework-core-and-asp-net-core/ Entity Framework Core (EF Core) is the newest database programming framework for .NET developers. It’s an obvious choice for ASP.NET Core developers. To that end, this article illustrates how to utilize Entity Framework Core for performing CRUD (create, read, update, and delete) operations on data. Note: This article uses RC2 of EF Core. Although there […]

The post Performing Database Operations using Entity Framework Core and ASP.NET Core appeared first on CodeGuru.

]]>
Entity Framework Core (EF Core) is the newest database programming framework for .NET developers. It’s an obvious choice for ASP.NET Core developers. To that end, this article illustrates how to utilize Entity Framework Core for performing CRUD (create, read, update, and delete) operations on data.

Note: This article uses RC2 of EF Core. Although there won’t be many code level changes under the final version, you may need to adjust the package references accordingly.

Create and Configure the Web Application

To begin, create a new ASP.NET Web Application using Visual Studio 2015. You may read this article for quick instructions to do just that. Once the Web application is created, open the Project.json file and add the Entity Framework-specific entries. The following markup shows the relevant entries of Project.json.

"Microsoft.EntityFrameworkCore.SqlServer":
   "1.0.0-rc2-final",
"Microsoft.EntityFrameworkCore.Tools": {
   "version": "1.0.0-preview1-final",
   "type": "build"
},

You also may consider modifying the tools section of Project.json file to include this:

"Microsoft.EntityFrameworkCore.Tools": {
   "version": "1.0.0-preview1-final",
   "imports": [
      "portable-net45+win8+dnxcore50",
      "portable-net45+win8"
   ]

You can grab the complete Project.json from the code download of this article.

Then, open the Startup class and modify it as shown in the following code:

public class Startup
{
   public static IConfiguration Configuration { get; set; }

   public Startup(IHostingEnvironment env)
   {
      ConfigurationBuilder builder =
         new ConfigurationBuilder();
      builder.SetBasePath(env.ContentRootPath);
      builder.AddJsonFile("AppSettings.json");
      Configuration = builder.Build();
   }

   public void ConfigureServices(IServiceCollection services)
   {
      services.AddMvc();
      services.AddEntityFrameworkSqlServer();
   }

   public void Configure(IApplicationBuilder app)
   {
      app.UseStaticFiles();
      app.UseMvc(routes =>
      {
         routes.MapRoute(
            name: "default",
            template: "{controller=Home}/
               {action=Index}/{id?}");
      });
   }
}

The preceding code consists of a constructor and two methods, ConfigureServices() and Configure(). The constructor reads the AppSettings.json file. The database connection string is typically stored in the AppSettings.json file. You can add this file to the project by using the Add New Item dialog and then add the following database connection string to it:

{
   "Data": {
      "DefaultConnection": {
         "ConnectionString": "Server=.;
            Database=EFCoreCRUDDemo;
            Trusted_Connection=True;"
      }
   }
}

This configuration is read inside the Startup constructor and is loaded into a static property, Configuration. We do this so that the configuration information can be retrieved anywhere in the application.

Note: There are better ways, such as DI, to pass configuration information to the rest of the application. However, to keep things simple, this example uses a static variable.

The ConfigureServices() method adds MVC and Entity Framework for SQL Server services to the container.

Creating the DbContext and Entity Class

Now that you have created and configured the project, add a Models folder to it and add a class named Customer. The Customer entity class is shown in the next code:

[Table("Customers")]
public class Customer
{
   [Key]
   [Required]
   [StringLength(5)]
   public string CustomerID { get; set; }
   [Required]
   [StringLength(30)]
   public string CompanyName { get; set; }
   [Required]
   [StringLength(40)]
   public string ContactName { get; set; }
   [Required]
   [StringLength(40)]
   public string Country { get; set; }
}

The [Table] attributes added to the Customer class indicates that it maps with the underlying entity maps to the Customers table of the database. The Customer class has four properties: CustoemrID, CompanyName, ContactName, and Country. These properties also have data annotations for the sake of validation. These attributes also are used during the database creation process (more on that later).

Then, add the DbContext class named AppDbContext. The AppDbContext class is shown below:

public class AppDbContext:DbContext
{
   public DbSet<Customer> Customers { get; set; }

   protected override void OnConfiguring
      (DbContextOptionsBuilder optionsBuilder)
   {
      optionsBuilder.UseSqlServer(Startup.Configuration
         ["Data:DefaultConnection:ConnectionString"]);
   }
}

The AppDbContext class inherits from the DbContext base class and overrides the OnConfiguring() method of the base class. Inside the OnConfiguring() method, the code calls the UseSqlServer() method of DbContextOptionsBuilder and passes it a database connection string. Notice how the database connection string is read using the Configuration static property. The AppDbContext class also has a Customers DbSet.

Creating the HomeController

Now, add a Controllers folder to the project and add a HomeController class to it. The HomeController class consists of six actions: Index(), two Insert() variations, two Update() variations, and Delete(). The Index() action is shown below:

public IActionResult Index()
{
   using (AppDbContext db = new AppDbContext())
   {
      var query = from c in db.Customers
                  orderby c.CustomerID ascending
                  select c;
      return View(query.ToList());
   }
}

The Index() action instantiates the AppDbContext and fetches all the Customer records. A List of Customer objects is passed to the Index view as its model.

The Insert() method has two overloads, one that handles GET requests and the other that handles POST requests. These variations are shown below:

public IActionResult Insert()
{
   return View();
}

[HttpPost]
public IActionResult Insert(Customer obj)
{
   if (ModelState.IsValid)
   {
      using (AppDbContext db = new AppDbContext())
      {
         db.Customers.Add(obj);
         db.SaveChanges();
      }
   }
   return View(obj);
}

The first Insert() action simply returns an empty Insert view to the browser. The second Insert() action is called when the user fills the Insert view and clicks the Save button. Through the model binding, a Customer object is received and is added to the Customers DbSet. The SaveChanges() method is called to persist the changes to the database.

The Update() actions are similar to the Insert() actions with a little change.

public IActionResult Update(string id)
{
   using (AppDbContext db = new AppDbContext())
   {
      Customer obj = db.Customers.Where(c => c.CustomerID ==
         id).SingleOrDefault();
      return View(obj);
   }
}

[HttpPost]
public IActionResult Update(Customer obj)
{
   if (ModelState.IsValid)
   {
      using (AppDbContext db = new AppDbContext())
      {
         db.Entry(obj).State = EntityState.Modified;
         db.SaveChanges();
      }
   }
   return View(obj);
}

The first Update() action receives a CustomerID through the id route parameter. It then fetches an existing Customer based on this CustomerID. The Customer object thus obtained is passed to the Update view. This is done so that the Update view can display existing customer data for modification.

The second Update() is called when the user modifies a customer and clicks the Save button. This method sets the State property to Modified to mark that the entity is a modified one. Then, SaveChanges() is called to save the changes to the physical database.

The Delete() action is quite straightforward and is as follows:

public IActionResult Delete(string id)
{
   using (AppDbContext db = new AppDbContext())
   {
      Customer obj = db.Customers.Where(c => c.CustomerID ==
         id).SingleOrDefault();
      db.Customers.Remove(obj);
      db.SaveChanges();
      return RedirectToAction("Index");
   }
}

The Delete() action receives a CustomerID through the id route parameter. The code then finds an existing Customer entry matching that CustomerID. The Customer object is then deleted from the DbSet using the Remove() method. The SaveChanges() method is called as before to persist the changes. Once a record is deleted, the user is taken back to the Index page by using the RedirectToAction() method.

Creating the Views

Now, add a Views folder under the project folder and also add a Home subfolder under it. Then, add an Index.cshtml view file to the Views > Home folder. The Index view is shown below:

@model List<Customer>

<html>
   <head>
      <title>Index</title>
   </head>
   <body>
      <h1>List of Customers</h1>

      <a asp-action="Insert" asp-controller="Home">
         Add New Customer</a>
      <br />

      <table cellpadding="10">
         @foreach (var item in Model)
         {
            <tr>
               <td>@item.CustomerID</td>
               <td>@item.CompanyName</td>
               <td>@item.ContactName</td>
               <td>@item.Country</td>
               <td><a asp-action="Update" asp-controller="Home"
                  asp-route-id="@item.CustomerID">Edit</a></td>
               <td><a asp-action="Delete" asp-controller="Home"
                  asp-route-id="@item.CustomerID">Delete</a></td>
               </tr>
            }
         </table>
      </body>
</html>

The @model directives are used to specify the model to be a List of Customer objects. A table is then rendered by using a foreach loop. The table displays the CustomerID, CompanyName, ContactName, and Country. The last two columns of the table display hyperlinks to the Update and Delete actions. At the top, there is a hyperlink to Insert action. Notice how the code uses tag helpers to display the links. The asp-action, asp-controller, and asp-route-id attributes of the anchor tag helper indicate the name of the action, name of the controller, and id route parameter value, respectively.

Figure 1 shows a sample run of the Index view once the application is complete:

Crud1
Figure 1: Following a sample run of the Index view

Now, add Insert view to the Views > Home folder and key in the following markup to it. Add the following markup to the Insert view:

@model Customer

<html>
   <head>
      <title>Add New Customer</title>
      <script src="~/Scripts/jquery-2.1.1.js"></script>
      <script src="~/Scripts/jquery.validate.js"></script>
      <script src="~/Scripts/jquery.validate.unobtrusive.js"
         ></script>
   </head>
   <body>
      <h1>Add New Customer</h1>

      <a asp-action="Index" asp-controller="Home">Back</a>
      <br />

      <form asp-action="Insert" asp-controller="Home">
         <table>
             <tr>
               <td><label asp-for="CustomerID">Custoemr ID :
                  </label></td>
               <td><input type="text" asp-for="CustomerID" />
                  </td>
            </tr>
            <tr>
               <td><label asp-for="CompanyName">Company Name :
                  </label></td>
               <td><input type="text" asp-for="CompanyName" />
                  </td>
            </tr>
            <tr>
               <td><label asp-for="ContactName">Contact Name :
                  </label></td>
               <td><input type="text" asp-for="ContactName" />
                  </td>
            </tr>
            <tr>
               <td><label asp-for="Country">Country :</label></td>
               <td><input type="text" asp-for="Country" /></td>
            </tr>
            <tr>
               <td><input type="submit" value="Save" /></td>
            </tr>
         </table>
         <br />
         <div asp-validation-summary="All"></div>
      </form>
   </body>
</html>

The Insert view sets the model to Customer by using the @model directive. The form tag helper is used to render a <form> element. The asp-action and asp-controller attributes indicate that the form will be POSTed to the Insert() action of the HomeController. Inside, the code uses label and input tag helpers to display labels and textboxes, respectively. A submit button submits the form to the specified action. Notice that a <div> also is used to display validation summary errors. Figure 2 shows how the Insert view looks like at run time.

Crud2
Figure 2: The Insert view at run time

The Update view is quite similar to the Insert view and hence not discussed here.

Creating the Database

Now that you have created the model-view-controller required by the application, proceed to create the database required by the application. Although you can use SQL Server manager or Visual Studio database tools to create the database, here we will use EF Core command line tools.

Open a command prompt and navigate to the project root folder. Then, issue the following two commands, one after the other.

> dotnet ef migrations add MyMigrations
> dotnet ef database update

The first command adds a Migrations folder under the project folder. The folder contains certain EF migration-related classes. The second command applies the migrations created earlier to the database. These command automatically read the AppDbContext, entity classes, and the connection string to create the required database and tables. Figure 3 shows the Customers table of the EFCoreCRUDDemo database (we specified it in the AppSettings.json file).

Crud3
Figure 3: The Customers table of the EFCoreCRUDDemo database

Notice how the column lengths are derived from the [StringLength] attributed added to the properties.

This completes the application. You can now run it and test the CRUD operations.

Injecting DbContext Using DI Features

In the preceding example, you manually instantiated the AppDbContext in the controller. You also can inject the DbContext into the controller using the DI features. Let’s see how.

Modify the ConfigureServices() method of Startup class as follows:

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   services.AddEntityFrameworkSqlServer();
   services.AddDbContext<AppDbContext>(o =>
      o.UseSqlServer(Configuration
      ["Data:DefaultConnection:ConnectionString"]));
}

Here, you registered the DbContext with the DI framework. Because you specify the database connection string while registering the DbContext, you can remove the OnConfiguring() method from the AppDbContext class. The modified AppDbContext will look like this:

public class AppDbContext:DbContext
{
   public AppDbContext(DbContextOptions<AppDbContext>
      options):base(options)
   {
   }
   public DbSet<Customer> Customers { get; set; }
}

Notice that the AppDbContext now has a constructor that takes a DbContextOptions<TContext> parameter.

Then, modify the HomeController to receive the injected AppDbContext. This is shown below:

public class HomeController : Controller
{
   private AppDbContext db = null;

   public HomeController(AppDbContext db)
   {
      this.db = db;
   }
   ....
   ....
   ....
   ....
}

You now can use the db anywhere in the HomeController rather than creating your own instance of AppDbContext.

Download the Code

You can download the code that accompanies the article here.

The post Performing Database Operations using Entity Framework Core and ASP.NET Core appeared first on CodeGuru.

]]>
Your First ASP.NET Core 1.0 App https://www.codeguru.com/dotnet/your-first-asp-net-core-1-0-app/ Wed, 29 Jun 2016 07:15:00 +0000 https://www.codeguru.com/uncategorized/your-first-asp-net-core-1-0-app/ Introduction Recently, Microsoft released RC2 of ASP.NET Core 1.0. You can build ASP.NET Core 1.0 applications using Visual Studio 2015. There is a Web Application project template that creates a basic Web application for you. This template adds several pieces of a basic Web application. However, for the sake of learning, may want to skip […]

The post Your First ASP.NET Core 1.0 App appeared first on CodeGuru.

]]>
Introduction

Recently, Microsoft released RC2 of ASP.NET Core 1.0. You can build ASP.NET Core 1.0 applications using Visual Studio 2015. There is a Web Application project template that creates a basic Web application for you. This template adds several pieces of a basic Web application. However, for the sake of learning, may want to skip this template and create an empty Web application. You then can add the required pieces yourself. To that end, this article illustrates how an ASP.NET Core 1.0 application can be built using the Empty project template.

Note: This article uses RC2 of ASP.NET Core 1.0. Make sure to install it on your machine before you follow the instructions discussed below. To know how to install RC2 of ASP.NET Core 1.0, you may want to read this article.

Creating a New Project

Let’s begin by creating a new project in Visual Studio 2015. Select the File > New Project menu option to open the New Project dialog, as shown in Figure 1:

First1
Figure 1: Creating a new project

As you can see, there are three items in the dialog. The first item is for creating traditional ASP.NET Web applications using Web Forms and MVC. The second item is for creating ASP.NET Core 1.0 applications that target .NET Core 1.0. Finally, the third item is for creating ASP.NET Core 1.0 applications that target .NET Framework. For this example, select ASP.NET Core Web Application entry, give some project name, and click OK.

You then can select a project template, as shown in Figure 2:

First2
Figure 2: Selecting a project template

As you can see, there are three project templates, namely Empty, Web API, and Web Application. Select the Empty project template and click OK. This will create a new project using the empty template and your Solution Explorer will resemble Figure 3:

First3
Figure 3: Viewing the Solution Explorer

Add Required Packages by Using Project.json

Open the Project.cs file and modify its dependencies section as follows:

"dependencies": {
     "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "type": "platform"
   },
   "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
   "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
   },
   "Microsoft.AspNetCore.Server.IISIntegration":
      "1.0.0-rc2-final",
   "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
   "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
   "Microsoft.Extensions.Configuration.EnvironmentVariables":
      "1.0.0-rc2-final",
   "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
   "Microsoft.Extensions.Configuration.Abstractions":
      "1.0.0-rc2-final",
   "Microsoft.AspNetCore.Http.Extensions": "1.0.0-rc2-final"
}

Especially notice the entries marked in bold letters. These assemblies are important for any ASP.NET Core 1.0 application. Also, ensure that the frameworks section matches the following:

"frameworks": {
   "netcoreapp1.0": {
      "imports": [
         "dotnet5.6",
         "dnxcore50",
         "portable-net45+win8"
      ]
   }
}

Once you modify the Project.json file, you may right-click the References folder in the Solution Explorer and click the Restore Packages option.

Configure the Application Startup

Now that you have added the required NuGet packages, let’s configure the application startup. You do that by using the Startup class. So, open the Startup.cs file and add the following code to it:

public class Startup
{
   public Startup(IHostingEnvironment env)
   {
      var builder = new ConfigurationBuilder();
      builder.SetBasePath(env.ContentRootPath);
      builder.AddJsonFile("appsettings.json",
         optional: true, reloadOnChange: true);
      IConfiguration config = builder.Build();
   }

   public void ConfigureServices(IServiceCollection services)
   {
      services.AddMvc();
   }

    public void Configure(IApplicationBuilder app)
   {
      app.UseStaticFiles();
      app.UseMvc(routes =>
      {
         routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/
               {id?}");
      });
   }
}

The Startup class consists of a constructor and two methods: ConfigureServices() and Configure(). Let’s examine them one by one.

The Startup constructor receives the IHostingEnvironment parameter through Dependency Injection. Inside, a ConfigurationBuilder object is created to read the application configuration file. The SetBasePath() method sets the base path where configuration files are located. In this case, ContentRootPath returns the physical path of the project root folder. AddJsonFile() adds an application configuration file that is in JSON format to the ConfigurationBuilder. In this case, we use AppSettings.json. You will create this file in the next section. Finally, the Build() method of ConfigurationBuilder is called to load the configuration settings into an IConfiguration object.

You will revisit the Startup constructor in the next section.

The ConfigureServices() method is automatically called by the ASP.NET Core framework and is intended to add the services required by the application. In this case, the AddMvc() method indicates that ASP.NET Core MVC 1.0 is to be used.

The Configure() method also is called automatically by the framework and is used to configure the HTTP pipeline. In this case, it calls the UseStaticFiles() method to enable the support for static files. It also calls UseMvc() to add MVC and also configures the default routing of the application.

Adding an Application Configuration File

Unlike ASP.NET, where an application’s configuration is stored in the web.config file, ASP.NET Core uses a JSON file to store application configuration. An application’s configuration includes things such as database connection strings and any application-specific pieces of information that you don’t want to embed directly in the source code.

To add a configuration file, right-click the project root folder and select Add > New Item. Then, select the ASP.NET Configuration file (ensure that ASP.NET is selected in the left-hand side pane).

First4
Figure 4: Adding a configuration file

The default name given to this file is AppSettings.json. Once the file gets added to the project, open the file and add the following JSON markup into it:

{
   "MySettings": {
      "Title" :  "This is Website Title",
      "Email" :  "contact@localhost"
   },

   "Data": {
      "DefaultConnection": {
         "ConnectionString": "Server=(localdb)
            \\MSSQLLocalDB;Database=
            _CHANGE_ME;Trusted_Connection=True;"
      }
   }
}

The AppSettings.json file contains two sections: MySettings and Data. The MySettings section is important for our example because we will use it later. The MySettings section consists of two sub-keys, namely Title and Email. These keys hold the corresponding values, as shown in the markup.

There can be multiple ways to access these applications’ settings in an application. Let’s use a simplistic approach for our example. Add a class, named AppSettings, to your project and write the following code into it:

public class AppSettings
{
   public static string Title { get; set; }
   public static string Email { get; set; }
}

The AppSettings class consists of two static properties—Title and Email—to hold the respective values from the MySettings section.

Now, open the Startup class again and modify its constructor as shown below:

public Startup(IHostingEnvironment env)
{
   var builder = new ConfigurationBuilder();
   builder.SetBasePath(env.ContentRootPath);
   builder.AddJsonFile("appsettings.json", optional: true,
      reloadOnChange: true);
   IConfiguration config = builder.Build();
   AppSettings.Title = config["MySettings:Title"];
   AppSettings.Email = config["MySettings:Email"];
}

The above code reads the Title and Email keys under the MySettings section using the IConfiguration object. The Title and Email values then are assigned to the respective properties of the AppSettings class. Once assigned, you can read them anywhere in the application.

Adding Models, Views, and Controllers

Now, add three folders under the project root folder: Models, Views, and Controllers. These folders will hold the respective pieces of the application. Right-click the Models folder and select the Add > Class menu option. Name the class Employee and write the following code in it.

public class Employee
{
   public int EmployeeID { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

The Employee class consists of three public properties, namely EmployeeID, FirstName, and LastName. Then, right-click the Controllers folder and open the Add New Item dialog. Add HomeController class to the project.

First5
Figure 5: Adding the HomeController class

Modify the Index() action of the HomeController as shown below:

public IActionResult Index()
{
   ViewBag.Title = AppSettings.Title;
   ViewBag.Email = AppSettings.Email;

   Employee emp = new Employee();
   emp.EmployeeID = 1;
   emp.FirstName = "Nancy";
   emp.LastName = "Davolio";

   return View(emp);
}

The Index() action sets two ViewBag properties, namely Title and Email, by reading the AppSettings class properties. It also creates an Employee object and assigns its property values. The Employee object is passed to the Index view as its model.

Now, add a Home subfolder under the Views folder and add a MVC view page to it.

First6
Figure 6: Adding a Home subfolder

Write the following HTML markup and Razor code in the Index view.

@model FirstAspNetCoreRC2Empty.Models.Employee

<html>
    <head>
      <title>Page Title</title>
   </head>
   <body>
      <h1>@ViewBag.Title</h1>
      <h2>Welcome @Model.FirstName @Model.LastName!</h2>
      <div>
         <strong>Contact : <a href="mailto:@ViewBag.Email">
            @ViewBag.Email</a></strong>
      </div>
   </body>
</html>

The above markup outputs the Title ViewBag property in the page heading. It also displays a welcome message using the Employee model object properties. An email link is displayed using the Email ViewBag property.

This completes the application. Run the application and see if it works as expected. Figure 7 shows a sample run of the application.

First7
Figure 7: Running the application

Download the Code

You can download the code that accompanies this article from this link.

The post Your First ASP.NET Core 1.0 App appeared first on CodeGuru.

]]>
Top 10 Features of ASP.NET Core for ASP.NET MVC Developers https://www.codeguru.com/dotnet/top-10-features-of-asp-net-core-for-asp-net-mvc-developers/ Wed, 01 Jun 2016 07:15:00 +0000 https://www.codeguru.com/uncategorized/top-10-features-of-asp-net-core-for-asp-net-mvc-developers/ Introduction ASP.NET Core 1.0 (formerly ASP.NET 5) provides a revamped Web development framework geared towards the requirements of modern Web applications. The new framework, currently in RC1, requires you to learn many new concepts not found in ASP.NET MVC 5. To that end, this article enumerates a few important features that ASP.NET MVC 5 developers […]

The post Top 10 Features of ASP.NET Core for ASP.NET MVC Developers appeared first on CodeGuru.

]]>
Introduction

ASP.NET Core 1.0 (formerly ASP.NET 5) provides a revamped Web development framework geared towards the requirements of modern Web applications. The new framework, currently in RC1, requires you to learn many new concepts not found in ASP.NET MVC 5. To that end, this article enumerates a few important features that ASP.NET MVC 5 developers should know as they prepare to learn this new framework.

Note: This article is based on RC1 of ASP.NET Core 1.0. You can check the roadmap and the availability of latest releases of the framework here.

1. ASP.NET Core on Multiple Platforms

ASP.NET and the .NET framework are targeted towards the Windows platform. On the other hand, ASP.NET Core is developed to support multiple platforms including Windows, Mac, and Linux. ASP.NET Core is a part of .NET Core—a new modular framework that supports multiple platforms. This also means that, unlike ASP.NET web applications, primarily run under IIS, the ASP.NET Core applications can run under non-IIS Web servers. Figure 1 shows the role of the .NET Core and ASP.NET Core.

Core1
Figure 1: The role of the .NET Core and ASP.NET Core

As you can see, a Web application built with ASP.NET Core can target .NET Framework 4.6 or the .NET Core. The Web applications targeting .NET Framework 4.6 run only on the Windows platform. The Web applications targeting the .NET Core can run on Windows and non-Windows platforms. Of course, as on this writing .NET Core doesn’t offer the same rich functionality offered by .NET Framework 4.6.

Notice that, to develop Web applications using ASP.NET Core, you use ASP.NET Core MVC. Of course, additional frameworks (such as EF Core) and packages can be added as per your requirement.

2. Role of Project.json

ASP.NET Core uses a special file—Project.json—for storing all the project-level configuration information. Project.config can store many configuration settings, such as references to NuGet packages used in the project and target frameworks. For a complete list, you may go here.

Just to give you an idea as to how Project.json is structured, have a look at the following markup from a sample Project.json.

"dependencies": {
   "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
   "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
   "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
   "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
   "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
   "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
   "Microsoft.Extensions.Configuration.Abstractions":
      "1.0.0-rc1-final",
   "Microsoft.Extensions.Configuration.Json":
      "1.0.0-rc1-final",
   "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
   "EntityFramework.Commands": "7.0.0-rc1-final",
   "Microsoft.AspNet.Session": "1.0.0-rc1-final",
   "Newtonsoft.Json": "8.0.3"
}

The Project.json file stores configuration information in JSON format. The above markup shows a dependencies section that contains a list of NuGet packages required by the application. For example, the Web application under consideration requires the 6.0.0-rc1-final version of Microsoft.AspNet.Mvc assembly, and so on. Some other commonly used sections of Project.json are frameworks, commands, and sources.

3. Role of AppSettings.json

ASP.NET stores application configuration settings in Web.config. For example, developers use the <appSettings> section to store custom application settings, the <connectionStrings> section to store database connection strings, and so on. ASP.NET Core uses AppSettings.json to store such pieces of information. Consider the following configuration:

{
   "AppSettings": {
      "Title": "My ASP.NET Core Application"
   },

   "Data": {
      "DefaultConnection": {
         "ConnectionString": "data source=.;
            initial catalog=Northwind;integrated security=true"
      }
   }
}

The preceding JSON markup consists of two properties or keys, namely AppSettings and Data. The AppSettings property holds a sub-key named Title. The Title sub-key has a string value of “My ASP.NET Core Application”. Similarly, the Data key has a DefaultConnection sub-key. The DefaultConnection in turn has a ConnectionString sub-key.

You can read the values stored in AppSettings.json using ConfigurationBuilder and IConfiguration (as discussed later).

4. Application Startup

In ASP.NET, Global.asax acts as the entry point for your application. You can wire various event handlers for events, such as Application_Start and Session_Start, in the Global.asax file. In ASP.NET Core, the application startup takes place quite differently—it happens through a Startup class. Consider one such Startup class, as shown below:

public class Startup
{
   public Startup(IHostingEnvironment env,
      IApplicationEnvironment app)
   {
      ConfigurationBuilder builder = new ConfigurationBuilder();
      builder.SetBasePath(app.ApplicationBasePath);
      builder.AddJsonFile("appsettings.json");
      IConfigurationRoot config = builder.Build();
      string str = config.Get<string>
         ("Data:DefaultConnection:ConnectionString");
      // do something with str
   }

   public void ConfigureServices(IServiceCollection services)
      {
         services.AddMvc();
         services.AddEntityFramework()
                 .AddSqlServer();
   }

   public void Configure(IApplicationBuilder app)
   {
      app.UseStaticFiles();
      app.UseMvc(routes =>
      {
         routes.MapRoute(
            name: "default",
            template: "{controller=Home}/
               {action=Index}/{id?}");
         });
      }

   public static void Main(string[] args) =>
      WebApplication.Run<Startup>(args);
}

The Startup class shown above begins with a constructor. The constructor loads the AppSettings.json file using ConfigurationBuilder class. The Get() method then is used to read the database connection string stored in the AppSettings.json file.

The ConfigureServices() method adds the services required by the application. For example, here you add MVC and Entity Framework to the services collection.

The Configure() method specifies and configures the services added earlier for application’s use. For example, the MVC routing is configured in the code shown above.

Finally, the Main() method acts as an entry point (quite similar to console applications) for the application.

5. Tag Helpers

In ASP.NET MVC 5, you used HTML helpers such as BeginForm(), LabelFor(), and TextBoxFor() to render forms and form fields. You can continue to use HTML helpers in ASP.NET Core, also. But there is a better alternative: Tag Helpers. Tag helpers take the form of standard HTML tags with certain special asp-* attributes added to them. Consider the following markup that renders a form:

<form asp-controller="Home" asp-action="Save" method="post">
   <table border="1" cellpadding="10">
      <tr>
          <td><label asp-for="FirstName">First Name :</label></td>
          <td><input type="text" asp-for="FirstName" /></td>
      </tr>
      <tr>
          <td><label asp-for="LastName">Last Name :</label></td>
          <td><input type="text" asp-for="LastName" /></td>
      </tr>
      <tr>
          <td><label asp-for="Email">Email :</label></td>
          <td><input type="text" asp-for="Email" /></td>
      </tr>
      <tr>
          <td><label asp-for="Phone">Phone :</label></td>
          <td><input type="text" asp-for="Phone" /></td>
      </tr>
        <tr>
          <td colspan="2">
             <input type="submit" value="Submit" />
          </td>
      </tr>
   </table>
</form>

Notice the attributes that begin with asp-. They are defined by the tag helpers. For example, the form tag helper uses asp-controller attribute to specify the target controller name and asp-action attribute to specify the target action method name. Similarly, asp-for attributes used with label and input tag helpers bind a label or a textbox to a model property. Tag helpers are more convenient to use than HTML helpers because their syntax closely resembles the HTML markup.

6. View Components

In MVC 5, you used partial views as a means to reuse markup and code. ASP.NET Core introduces View Components—a more powerful and flexible alternative. A view component consists of a class typically inherited from ViewComponent base class and a view file containing the required markup. This programming model is quite similar to the one used by controllers and views. It allows you to separate code and markup from each other—code in the view component class and markup in a view. Once created, you can use a view component on a view by using the @Component.Invoke() method.

You may read more about view components here.

7. Dependency Injection

ASP.NET Core provides an inbuilt dependency injection framework. The DI framework of ASP.NET Core offers four lifetime modes for a type being injected:

  • Singleton: An object of a service (the type to be injected) is created and supplied to all the requests to that service. So, basically all requests get the same object to work with.
  • Scoped: An object of a service is created for each and every request. So, each request gets a new instance of a service to work with.
  • Transient: An object of a service is created every time an object is requested.
  • Instance: In this case, you are responsible for creating an object of a service. The DI framework then uses that instance in singleton mode, mentioned earlier.

You register a type for DI in the Startup class as shown below:

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   services.AddSingleton<IMyService,MyService>();
}

Here, MyService is the type to be registered with the DI framework and implements IMyService. The AddSingleton() method registers this type for Singleton mode described above. Once a type is registered with the DI framework, you can inject it in a controller like this:

public class HomeController : Controller
{
   private IMyService obj;

   public HomeController(IMyService obj)
   {
      this.obj = obj;
   }
   ....
   ....
}

For more details about using these lifetime modes in ASP.NET Core, go here.

8. Gulp, Grunt, and Bower Support

Gulp and Grunt are JavaScript task runners. They help you automate commonly needed tasks, such as bundling JavaScript and CSS files, minifying JavaScript and CSS files, and compiling Less and Sass files (and many more). They are installed using npm (Node Package Manager). The ASP.NET Core project created using Visual Studio 2015 allows you to add Grunt and Gulp configuration files and also provides Task Runner Explorer to monitor the tasks. You may find more details about using Grunt and Gulp with ASP.NET Core here.

Bower is a package manager primarily for front-end packages. Front-end packages are the packages that you use in your Web pages, such as JavaScript libraries/frameworks and CSS files. For example, you may install jQuery in your ASP.NET Core project by using Bower. An ASP.NET Core project created using Visual Studio 2015 allows you to add a Bower configuration file. You also can work with the packages using the Manage Bower Packages menu option. Read more details about using Bower with ASP.NET Core.

9. Single Programming Model for MVC and Web API

In MVC 5, controllers inherit from the System.Web.Mvc.Controller base class. And, Web API 2 controllers inherit from System.Web.Http.ApiController. In ASP.NET Core, both of these frameworks are merged into a single framework. Thus, under ASP.NET Core, an MVC controller and Web API controller both inherit from Microsoft.AspNet.Mvc.Controller base class. You then can configure aspects such as HTTP verb mapping and the routing of the controllers as desired.

10. Static Files and the wwwroot Folder

In ASP.NET, there is no fixed location for storing static files such as image files, JavaScript files, and CSS files (developers often used a Content folder to store such files). In ASP.NET Core, all the static files are kept under the wwwroot folder (default). You also can change the name of this folder by using the Project.json file. Consider Figure 2, which shows how the wwwroot folder looks in the Solution Explorer.

Core2
Figure 2: The wwwroot folder

After deployment, the wwwroot becomes the Web application’s root. All the URLs to static files are resolved with respect to this folder. So, /images/logo.png expects logo.png to be present under the wwwroot/images folder.

Summary

ASP.NET Core 1.0 is a revamped framework geared towards modern cloud based, modular Web applications. Although the new framework preserves the fundamental concepts of MVC 5, ASP.NET developers will find many differences between MVC 5 and ASP.NET Core 1.0. This article enumerated the important new features/concepts that you need to understand to begin your journey with ASP.NET Core 1.0.

The post Top 10 Features of ASP.NET Core for ASP.NET MVC Developers appeared first on CodeGuru.

]]>
Implementing Sorting and Paging in the Web API Using OData Queries https://www.codeguru.com/csharp/implementing-sorting-and-paging-in-the-web-api-using-odata-queries/ Fri, 12 Sep 2014 07:15:00 +0000 https://www.codeguru.com/uncategorized/implementing-sorting-and-paging-in-the-web-api-using-odata-queries/ Introduction The client displaying data returned by a Web API may want to implement sorting or paging on the data being returned. Although there can be different ways to implement these features, a simple technique is to use OData support offered by the Web API. This article shows how to call a Web API by […]

The post Implementing Sorting and Paging in the Web API Using OData Queries appeared first on CodeGuru.

]]>
Introduction

The client displaying data returned by a Web API may want to implement sorting or paging on the data being returned. Although there can be different ways to implement these features, a simple technique is to use OData support offered by the Web API. This article shows how to call a Web API by using a client-side script and also shows how to implement Ajax-driven sorting and paging.

Defining the Requirements

In the example discussed in this article, you will meet the following requirements:

  • The data to be displayed is returned by a Web API.
  • The data should be displayed in an HTML table.
  • The column headings should be clickable. Clicking a column should sort the data shown in the table.
  • The sorting should be persistent and bidirectional. Clicking a column header should toggle the sort order between ascending and descending. The sort order must be persistent even when the page index changes.
  • The bottom of the table should display a pager row with page numbers. Clicking a page should display only the records belonging to that page.
  • The sorting as well as paging should be implemented by using Ajax calls.

Figure 1 shows the final outcome of the example discussed in this article.

Paging1
Figure 1: The completed table

As shown in Figure 1, the column headers are clickable hyperlinks. They don’t point to any specific resource. They are simply used to indicate a clickable heading. The same holds true for hyperlinks shown in the pager row of the table. The click event raised by a hyperlink is trapped by using jQuery code and the form is submitted to the server programmatically for further action.

Creating the Model

To begin developing this example, create a new ASP.NET Web Application by using a Web API project template (see Figure 2).

Paging2
Figure 2: Creating a new project

Then, right-click the Models folder and add a new ADO.NET entity data model for the Customers table of the Northwind database. Figure 3 shows the Customer entity class in the Visual Studio designer.

Paging3
Figure 3: The Customer entity class

In addition to the Customer entity class, you need an auxiliary class: SortingPagingInfo. This class contains all the settings used by the sorting and paging features, such as the field on which the data is to be sorted and the total number of pages. The SortingPagingInfo class is shown below:

public class SortingPagingInfo
{
   public string SortField { get; set; }
   public string SortDirection { get; set; }
   public int PageSize { get; set; }
   public int PageCount { get; set; }
   public int CurrentPageIndex { get; set; }
}

As you can see, the SortingPagingInfo class consists of five properties: SortField, SortDirection, PageSize, PageCount, and CurrentPageIndex. These property names are self explanatory and therefore are not discussed here.

Creating the Web API

This example uses OData support provided in the Web API. Data protocol allows you to create RESTful data services by exposing URI end points. The ASP.NET Web API supports OData queries so that your data can be consumed by the client over HTTP with the help of OData query options. If you are not familiar with this feature, you may consider reading this article first.

Once the model is ready, right-click the References folder and select the “Manage NuGet Packages” option. In the Manage NuGet Packages dialog, search for WebApi.OData and install the “Microsoft ASP.NET Web API 2.2 for OData v1.3” package. Along with the installation, other dependencies also will be added for you.

Paging4
Figure 4: Installing the “Microsoft ASP.NET Web API 2.2 for OData v1.3” package

Then, add a new Web API controller in the Controllers folder and name it CustomerController. This controller class is shown below:

public class CustomerController : ApiController
{
   [EnableQuery]
   public IQueryable<Customer> GetCustomers()
   {
      NorthwindEntities db = new NorthwindEntities();
      eturn db.Customers;
   }
}

As you can see, the CustomerController class contains only one method: GetCustomers(). This method is invoked from the client through a GET request and returns the required data. Notice that the GetCustomers() method is decorated with the [EnableQuery] attribute. The [EnableQuery] attribute enables OData support for the Web API. The return type of the method is IQueryable of Customer objects. Inside, it simply returns all the data from the Customers DbSet back to the caller. This is all you need to do in the Web API.

Creating the HomeController

Open the HomeController from the Controllers folder and modify the Index() action method as shown below. The Index() action sets the default values for the sorting and paging features.

public class HomeController : Controller
{
   public ActionResult Index()
   {
      using (NorthwindEntities db = new NorthwindEntities())
      {
         SortingPagingInfo info = new SortingPagingInfo();
         info.SortField = "CustomerID";
         info.SortDirection = "asc";
         info.PageSize = 10;
         info.PageCount = Convert.ToInt32(Math.Ceiling((double)(db.Customers.Count()
            / info.PageSize)));
         info.CurrentPageIndex = 0;
         ViewBag.SortingPagingInfo = info;
         return View();
      }
   }
}

The Index() action method creates an instance of the SortingPagingInfo class created earlier and sets its properties, such as SortField, SortDirection, PageSize, PageCount, and CurrentPageIndex. The SortingPagingInfo object is passed to the view by using a ViewBag property so that these values can be utilized on the view.

Creating the Index View

Now comes the important part: consuming the Web API and implementing the sorting and paging features. Add the Index view and write the following code in it:

<h1>List of Customers</h1>
@{
    SortingPagingInfo info = ViewBag.SortingPagingInfo;
}
@using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
   @Html.Hidden("SortField", info.SortField)
   @Html.Hidden("SortDirection", info.SortDirection)
   @Html.Hidden("PageCount", info.PageCount)
   @Html.Hidden("PageSize", info.PageSize)
   @Html.Hidden("CurrentPageIndex", info.CurrentPageIndex)
   <table border="1" cellpadding="10">
      <tr class="headerRow">
         <th><a href="#" data-sortfield="CustomerID"
            class="header">CustomerID</a></th>
         <th><a href="#" data-sortfield="CompanyName"
            class="header">CompanyName</a></th>
         <th><a href="#" data-sortfield="ContactName"
            class="header">ContactName</a></th>
         <th><a href="#" data-sortfield="Country"
            class="header">Country</a></th>
      </tr>
      <tr class="pagerRow">
         <td colspan="4">
            @for (var i = 0; i < info.PageCount; i++)
            {
               <a href="#" data-pageindex="@i"
                  class="pager">@(i + 1)</a>
            }
         </td>
      </tr>
   </table>
}

The preceding code grabs the SortingPagingInfo object passed through the ViewBag and transfers its properties into five hidden fields. This is required because these values need to be accessed from jQuery code (discussed later). An HTML table is used to display the data. Notice how the table headers are shown. Each column header consists of an anchor element whose data-sortfield custom data attribute is set to the column name it represents. This data-sortfield attribute is used to decide the sorting order when a user clicks on the header. Also, notice that all the header anchor links have a header CSS class associated with them. This class is used as a selector in the jQuery code.

The pager row simply displays anchor elements based on the PageCount. Notice that each pager link stores its index in a data-pageindex attribute and that the table row has the pagerRow CSS class.

Next, add a script reference to the jQuery library and also add an empty script block.

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
   ...
</script>

Then, add a JavaScript function, GetData(), inside the <script> block. This function calls the Web API and retrieves the required data.

function GetData()
{

  var sortfield = $("#SortField").val();
   var sortdirection = $("#SortDirection").val();
   var currentpageindex = $("#CurrentPageIndex").val();
   var pagesize = $("#PageSize").val();
   var url = "/api/customer";
   var query = "";
   switch (sortfield) {
      case "CustomerID":
         query = (sortdirection == "asc" ? "$orderby=CustomerID asc" :
            "$orderby=CustomerID desc");
         break;
      case "CompanyName":
         query = (sortdirection == "asc" ? "$orderby=CompanyName asc" :
            "$orderby=CompanyName desc");
         break;
      case "ContactName":
         query = (sortdirection == "asc" ? "$orderby=ContactName asc" :
            "$orderby=ContactName desc");
         break;
      case "Country":
         query = (sortdirection == "asc" ? "$orderby=Country asc" :
            "$orderby=Country desc");
         break;
   }
   query += "&$skip=" + (currentpageindex * pagesize) + "&$top=" + pagesize;
   url += "?" + query;
   $.getJSON(url, function (data) {
      $("table").find('tr').slice(1, -1).remove();
      for (var i = 0;i<data.length;i++)
      {
         var html = '<tr>';
         html += '<td>' + data[i].CustomerID + '</td>';
         html += '<td>' + data[i].CompanyName + '</td>';
         html += '<td>' + data[i].ContactName + '</td>';
         html += '<td>' + data[i].Country + '</td>';
         html += '</tr>';
         $(".pagerRow").before(html);
      }
   });
}

The GetData() function grabs the values from the SortField, SortDirection, CurrentPageIndex, and PageSize hidden fields. As mentioned earlier, you will be sending an OData query to the Web API to retrieve data. This query needs to have three parameters: $orderby, $skip, and $top.

The switch block determines and adds the $orderby parameter of the OData query. Notice how the “asc” and “desc” clause is being added. After the switch block, the $skip parameter is added by calculating its value as (currentpageindex * pagesize). Finally, the $top parameter is set to the value of the pagesize variable. This way, the Web API has everything it needs to sort and page the data under consideration.

The actual Ajax call to the Web API is made by using $.getJSON() of jQuery. The first parameter of $.getJSON() is the URL pointing to the Web API: /api/customer. The second parameter is a callback function that gets invoked when the call is complete.

The callback function receives the Customer data in the form of an array. Before adding this data to the table, the existing data (if any) is removed by slicing the table. This is done by using the slice() method. A for loop iterates through the data and adds a table row filled with the Customer data to the table by using the before() method.

The GetData() function is called from the ready() method of jQuery. This is shown below:

$(document).ready(function () {
   GetData();
   $(".header").click(function (evt) {
      var sortfield = $(evt.target).data("sortfield");
      if ($("#SortField").val() == sortfield) {
         if ($("#SortDirection").val() == "asc") {
            $("#SortDirection").val("desc");
         }
         else {
            $("#SortDirection").val("asc");
         }
      }
      else {
         $("#SortField").val(sortfield);
         $("#SortDirection").val("asc");
      }
      evt.preventDefault();
      GetData();
   });
   $(".pager").click(function (evt) {
      var pageindex = $(evt.target).data("pageindex");
      $("#CurrentPageIndex").val(pageindex);
      evt.preventDefault();
      GetData();
   });
});

As soon as the page loads in the browser, you need to display the first page of data. So, a call to GetData() is made immediately inside the ready() method.

A class selector is used to retrieve all the header anchor elements (header CSS class) and a click event handler is wired to them. The click event handler basically checks the header element that was clicked and accordingly sets the SortField hidden field. This is done by using the data-sortfield custom data attribute of the anchor element under consideration. Notice that if a header element is clicked multiple times, the SortDirection hidden field toggles its value between asc and desc. Then, GetData() is called to get the data as per the new sort order.

On similar lines, the click event handler of pager hyperlinks grabs the data-pageindex custom data attribute and sets the CurrentPageIndex hidden field. GetData() is called again so that the new page of data can be displayed.

That’s it! Run the application and test whether sorting and paging works as expected.

Summary

The data returned from the Web API is often displayed in a tabular format. You may need to provide sorting and paging for such a table. By using OData support offered by the Web API, client-side script, and Ajax calls, you easily can implement persistent and bidirectional sorting as well as paging. This article illustrated how this can be accomplished.

Extra Reading Links

The post Implementing Sorting and Paging in the Web API Using OData Queries appeared first on CodeGuru.

]]>
Implementing Sorting and Paging in ASP.NET MVC https://www.codeguru.com/dotnet/implementing-sorting-and-paging-in-asp-net-mvc/ Fri, 05 Sep 2014 07:15:00 +0000 https://www.codeguru.com/uncategorized/implementing-sorting-and-paging-in-asp-net-mvc/ Introduction Displaying records in a table is a very common requirement in many web applications. Such a table also needs facilities such as sorting the data based on a specific column and pagination for the sake of easy navigation and display. Unlike ASP.NET web forms, MVC doesn’t have readymade server controls such as GridView to […]

The post Implementing Sorting and Paging in ASP.NET MVC appeared first on CodeGuru.

]]>
Introduction

Displaying records in a table is a very common requirement in many web applications. Such a table also needs facilities such as sorting the data based on a specific column and pagination for the sake of easy navigation and display. Unlike ASP.NET web forms, MVC doesn’t have readymade server controls such as GridView to ease your job. One needs to either use a third-party helper or make some custom provision to accomplish this task. This article shows how persistent and bidirectional sorting as well as paging can be implemented in ASP.NET MVC without any external dependencies.

Defining the Requirements

In the example discussed in this article, you will meet the following requirements:

  • The data should be displayed in an HTML table.
  • The column headings should be clickable. Clicking on a column should sort the data shown in the table.
  • The sorting should be persistent and bidirectional. Clicking on a column header should toggle the sort order between ascending and descending. The sort order must be persistent even when the page index changes.
  • The bottom of the table should display a pager row with page numbers. Clicking on a page should display only the records belonging to that page.

Figure 1 shows the final outcome of the example discussed in this article.

Sorting01
Figure 1: The Customers list

As shown above, the column headers are clickable hyperlinks. They don’t point to any specific resource. They are simply used to indicate a clickable heading. The same holds true for hyperlinks shown in the pager row of the table. The click event raised by a hyperlink is trapped with jQuery code and the form is submitted to the server programmatically for further action.

Creating the Model

To develop this example, begin by creating a new ASP.NET MVC application. Right-click the Models folder and add a new ADO.NET entity data model for the Customers table of the Northwind database. Figure 2 shows the Customer entity class in the Visual Studio designer.

Sorting02
Figure 2: The Customer entity class properties

In addition to the Customer entity class, you need an auxiliary class—SortingPagingInfo. This class contains all the settings used by the sorting and paging features, such as the field on which the data is to be sorted and total number of pages. The SortingPagingInfo class is shown in the following code segment:

public class SortingPagingInfo
{
   public string SortField     { get; set; }
   public string SortDirection { get; set; }
   public int PageSize         { get; set; }
   public int PageCount        { get; set; }
   public int CurrentPageIndex { get; set; }
}

As you can see, the SortingPagingInfo class consists of five properties; they are SortField, SortDirection, PageSize, PageCount, and CurrentPageIndex. These property names are self explanatory and therefore are not discussed here.

Creating the Controller

Now that the model is ready, add a Home controller class in the Controllers folder. The HomeController class contains two action methods. The first action method serves the initial request and assigns default values and initial data to be displayed. This method is shown below:

public ActionResult Index()
{
   using (NorthwindEntities db = new NorthwindEntities())
   {
      SortingPagingInfo info = new SortingPagingInfo();
      info.SortField = "CustomerID";
      info.SortDirection = "ascending";
      info.PageSize = 10;
      info.PageCount = Convert.ToInt32(Math.Ceiling((double)(db.Customers.Count()
                     / info.PageSize)));
      info.CurrentPageIndex = 0;
      var query = db.Customers.OrderBy(c=>c.CustomerID).Take(info.PageSize);
      ViewBag.SortingPagingInfo = info;
      List<Customer> model = query.ToList();
      return View(model);
   }
}

As shown above, the Index() action method creates an instance of SortingPagingInfo and sets its properties. The default SortField is set to CustomerID and PageSize is set to 10. The PageCount is calculated with the help of the Ceiling() method. Initially, the first 10 records are to be displayed in a table. So, the Take() method is used to pick only the first ten records. The SortingPagingInfo object is passed to the view through the SortingPagingInfo ViewBag property. The model in the form of List of Customer objects is passed to the Index view.

When a user clicks the column heading or page number, the form is POSTed to the server and reaches the other Index() method. This Index() action is shown below:

[HttpPost]
public ActionResult Index(SortingPagingInfo info)
{
   using (NorthwindEntities db = new NorthwindEntities())
   {
      IQueryable<Customer> query = null;
      switch(info.SortField)
      {
         case "CustomerID":
            query = (info.SortDirection == "ascending" ?
                     db.Customers.OrderBy(c => c.CustomerID) :
                     db.Customers.OrderByDescending(c => c.CustomerID));
            break;
         case "CompanyName":
            query = (info.SortDirection == "ascending" ?
                     db.Customers.OrderBy(c => c.CompanyName) :
                     db.Customers.OrderByDescending(c => c.CompanyName));
            break;
         case "ContactName":
            query = (info.SortDirection == "ascending" ?
                     db.Customers.OrderBy(c => c.ContactName) :
                     db.Customers.OrderByDescending(c => c.ContactName));
            break;
         case "Country":
            query = (info.SortDirection == "ascending" ?
                     db.Customers.OrderBy(c => c.Country) :
                     db.Customers.OrderByDescending(c => c.Country));
            break;
      }
      query = query.Skip(info.CurrentPageIndex
            * info.PageSize).Take(info.PageSize);
      ViewBag.SortingPagingInfo = info;
      List<Customer> model = query.ToList();
      return View(model);
   }
}

The preceding Index() method has a parameter of type SortingPagingInfo. The model binding framework fills this object with the form field values (discussed later). A switch statement checks the SortField property of the SortingPagingInfo object. Based on the SortField and SortDirection properties, a query in the form of IQueryable is formed. Because you are interested only in the records belonging to the current page to be displayed, the Skip() and Take() methods are used. Notice how the Skip() method is used to skip certain records from the beginning of the result set and how Take() is used to pick only the desired number of records. The model in the form of a List of Customer objects is passed to the Index view as before.

Creating the View

After you create the controller, next create the Index view. Right-click any of the Index action methods and select the Add View option. Name the view as Index and it is the key in the following code to its <body>.

<h1>List of Customers</h1>
@{
   SortingPagingInfo info = ViewBag.SortingPagingInfo;
}

@using (Html.BeginForm("Index","Home",FormMethod.Post))
{
   @Html.Hidden("SortField",        info.SortField)
   @Html.Hidden("SortDirection",    info.SortDirection)
   @Html.Hidden("PageCount",        info.PageCount)
   @Html.Hidden("PageSize",         info.PageSize)
   @Html.Hidden("CurrentPageIndex", info.CurrentPageIndex)

   <table border="1" cellpadding="10">
      <tr>
         <th><a href="#" data-sortfield="CustomerID"
                         class="header">CustomerID</a></th>
         <th><a href="#" data-sortfield="CompanyName"
                         class="header">CompanyName</a></th>
         <th><a href="#" data-sortfield="ContactName"
                         class="header">ContactName</a></th>
         <th><a href="#" data-sortfield="Country"
                         class="header">Country</a></th>
      </tr>
      @foreach(var item in Model)
      {
         <tr>
            <td>@item.CustomerID</td>
            <td>@item.CompanyName</td>
            <td>@item.ContactName</td>
            <td>@item.Country</td>
         </tr>
      }
         <tr>
            <td colspan="4">
               @for(var i=0;i<info.PageCount;i++)
                  {
                     if(i==info.CurrentPageIndex)
                     {
                        <span>@(i+1)</span>
                     }
                     else
                     {
                        <a href="#" data-pageindex="@i"
                           class="pager">@(i + 1)</a>
                     }
               }
            </td>
         </tr>
   </table>
}

The code above grabs the SortingPagingInfo object passed through the ViewBag. Then comes the important piece of code. The settings from SortingPagingInfo bject are transferred into five hidden form fields. This is done by using the Hidden() HTML helper. Notice that names of these hidden fields are kept the same as the properties of the SortingPagingInfo class. This will enable the model binding framework to populate the SortingPagingInfo parameter of the second Index() action as expected. Also notice that the whole HTML table that displays the data is placed inside a <form> tag, by using the BeginForm() HTML helper.

The HTML table has four columns to display CustomerID, CompanyName, ContactName, and Country columns. The column headings are displayed using anchor elements. The data-sortfield custom data attributes of anchor elements are set to the actual column names. This way, you can keep the actual heading being displayed different from the column name (for example, you may display Customer ID in the heading whereas the data-sortfield will store CustomerID). The anchor elements have a CSS class set to header. This is primarily done to simplify the jQuery code (you may resort to some other selector to grab the anchor elements instead of using the class selector).

A foreach loop iterates through the model data and emits table rows containing the actual customer information. Although the Customer entity class has many properties, this example uses only four of them: CustomerID, CompanyName, ContactName, and Country.

The last row of the table represents the pager row. A for loop generates anchor elements representing the individual page number. The current page number is displayed in a <span> tag whereas other page numbers are rendered as anchor elements. The anchor elements acting as clickable page numbers have a CSS class of pager. Notice that the data-pageindex custom data attribute of the anchor elements is set to the zero-based page number. Just like the data-sortfield attribute, the data-pageindex attribute is used by the jQuery code.

Next, add a <script> reference to jQuery in the head section of the Index view. Also, add an empty <script> block and key in the following jQuery code.

$(document).ready(function () {
   $(".header").click(function (evt) {
      var sortfield = $(evt.target).data("sortfield");
      if ($("#SortField").val() == sortfield)
      {
         if($("#SortDirection").val()=="ascending")
         {
            $("#SortDirection").val("descending");
         }
         else
         {
            $("#SortDirection").val("ascending");
         }
      }
      else
      {
         $("#SortField").val(sortfield);
         $("#SortDirection").val("ascending");
      }
      evt.preventDefault();
      $("form").submit();
   });

   $(".pager").click(function (evt) {
      var pageindex = $(evt.target).data("pageindex");
      $("#CurrentPageIndex").val(pageindex);
      evt.preventDefault();
      $("form").submit();
   });
});

The preceding jQuery code consists of two click event handlers. The first piece of code selects all the anchors having its header in the CSS class (column headers). Inside, the code retrieves the data-sortfield custom data attribute using the jQuery data() method and stores it in a local variable. The if condition checks whether the user is clicking the same column header again. If so, the code toggles the sort direction from ascending to descending and vice versa; otherwise, the SortField hidden field is set to the value of data-sortfield and the SortDirection is set to ascending. After assigning SortField and SortDirection, the form is submitted programmatically using the submit() method.

The second piece of code deals with the click events of the pager anchor elements. It selects all the elements having the pager CSS class. The code then grabs the data-pageindex custom data attribute and stores it in a local variable. The CurrentPageIndex hidden field is set to this page index value and the form is submitted programmatically by using the submit() method.

Recollect that the BeginForm() helper sets the form action to Index and the method to POST. So, after submitting the form programmatically, it is handled by the second Index() action method.

That’s it! Run the application and test whether sorting happens in ascending as well as descending order. Also, test whether clicking a page number displays the correct records. Figure 3 shows a sample run with a PageSize of 5, CurrentPageIndex of 5 (page number 6), and records sorted in the descending order of Country column.

Sorting03
Figure 3: The Customers list, sorted in descending order on the Country column

Summary

Displaying data in HTML tables is a very common requirement in web applications. Such a display often needs features such as sorting and paging. This article discussed one easy way to implement persistent and bidirectional sorting as well as paging in ASP.NET MVC. You can customize the code discussed in this article to fine-tune the sorting and paging behavior of the resultant table.

Extra Reading Links

The post Implementing Sorting and Paging in ASP.NET MVC appeared first on CodeGuru.

]]>
Securing ASP.NET MVC Applications with ASP.NET Identity https://www.codeguru.com/dotnet/securing-asp-net-mvc-applications-with-asp-net-identity/ Fri, 15 Aug 2014 07:01:00 +0000 https://www.codeguru.com/uncategorized/securing-asp-net-mvc-applications-with-asp-net-identity/ Introduction ASP.NET offers Forms Authentication as one of the authentication schemes. Developers often use Forms Authentication in combination with membership, roles and profile features to provide security to their web applications. Over the years the needs of authentication schemes used in a web application have changed. To take into account these changing trends Microsoft has […]

The post Securing ASP.NET MVC Applications with ASP.NET Identity appeared first on CodeGuru.

]]>
Introduction

ASP.NET offers Forms Authentication as one of the authentication schemes. Developers often use Forms Authentication in combination with membership, roles and profile features to provide security to their web applications. Over the years the needs of authentication schemes used in a web application have changed. To take into account these changing trends Microsoft has released ASP.NET Identity – a new way to authenticate users of your web application. This article describes how ASP.NET Identity can be used in an ASP.NET MVC application from the ground up. 

Overview of ASP.NET Identity

Developers often use Forms Authentication combined with Membership, Roles and Profile features to secure their web applications. Over the years these features have become inadequate to deal with changing trends of web application security. For example, many modern web sites use Facebook or OAuth based external user credentials. ASP.NET membership has no inbuilt way to deal with these situations. There are many other limitations of the membership system such as rigid database structure and complex object model. We won’t go into the details of these limitations in this article. You may read the “Extra Reading Links” given at the end of this article.

ASP.NET Identity is a new authentication system that is intended to replace the existing membership system of ASP.NET. ASP.NET Identity is an OWIN (Open Web Interface for .NET) based library. Visual Studio 2013 project templates allow you to use ASP.NET Identity for securing the web application being created. Have a look at the following figure that shows the project template dialog of Visual Studio 2013.

Project Template Dialog of Visual Studio 2013
Project Template Dialog of Visual Studio 2013

When you select MVC project template you will see the Change Authentication button enabled. Clicking on the button will open the Change Authentication dialog as shown above. The default selection of “Individual User Accounts” indicates that user account information will be stored in the application database (that means users won’t use any external / OAuth based logins).

If you create an MVC project with this default selection, you will find that the project template includes AccountController and associated views for registering new users as well as for authenticating users. You will also find reference to a few OWIN assemblies added for you along with an OWIN startup class. Many beginners find this automatically added code difficult to understand. That is why this article shows you how to implement ASP.NET Identity in an empty MVC project from the ground up. Remember that this article discusses only the local user accounts. Any discussion of external logins (such as Facebook or any OAuth compatible system) is beyond the scope of this article.

Before you actually start the development of the example web application, it is important to familiarize yourself with the parts of ASP.NET Identity. Knowing these parts will let you code and use them easily in your web applications.

There are six important pieces of ASP.NET Identity system as far as local user accounts are concerned. They are briefly discussed below:

  • User
  • Role
  • User Manager
  • Role Manager
  • Authentication Manager
  • Entity Framework DbContext

A User object represents a user of the system. The basic authentication details such as user ID and password as well as profile information of a user make a User object. ASP.NET Identity comes with the IdentityUser class that captures basic authentication information. If you also need to capture profile information, you can create a custom class that inherits from the IdentityUser base class. This class is analogous to the MembershipUser class of the ASP.NET membership system.

A Role object represents a user role. At a minimum a role has a name with which it is identified in the system. The IdentityRole class of ASP.NET Identity provides this basic role. If you wish to add some more pieces to the role (say description of a role) then you can create a custom class that inherits from the IdentityRole base class.

A User Manager is a class that allows you to manager users. Creating user accounts, removing user accounts, changing passwords, adding / removing users to a role and such tasks can be performed using a user manager. ASP.NET Identity comes with the UserManager class that can be used for this purpose. This class is analogous to the Membership intrinsic object of the ASP.NET membership system.

A Role Manager is a class that allows you to manage roles. Creating a role, removing a role, checking whether a role exists in the system and such tasks can be performed using a role manager. ASP.NET Identity provides the RoleManager class that can be used for this purpose. This class is analogous to the Roles intrinsic object of the ASP.NET membership system.

All the classes mentioned above deal with users and roles respectively. These classes by themselves don’t perform any authentication. Authenticating a user – signing in and signing out a user – is the responsibility of Authentication Manager. The local user accounts can use cookie based authentication similar to Forms Authentication. ASP.NET Identity provides the IAuthenticationManager interface that represents an authentication manager. An authentication manager is analogous to the FormsAuthentication class of ASP.NET.

One important aspect of ASP.NET Identity is that the database table schema is not rigidly fixed as in the case of the ASP.NET membership system. ASP.NET Identity uses Entity Framework Code First approach to generate the table schema based on the user and role objects. That means for each piece of user profile a separate column is created in the database table. The following figure shows the sample tables created by ASP.NET Identity in a database.

 Sample Tables Created by ASP.NET Identity in a Database
Sample Tables Created by ASP.NET Identity in a Database

As you can see, all the tables that begin with “AspNet” are created by ASP.NET Identity. Notice that the AspNetUsers table that stores user information also contains profile information such as FullName, BirthDate and Bio as separate columns.

By default a separate database is created in the App_Data folder and all the above tables are created in that database. However, you can use an existing database for storing this information. If you decide to do so, the above tables will be created in the database you specify. To accomplish this you can create a custom DbContext class that inherits from the IdentityDbContext base class. While there is no analogy for this part in the ASP.NET membership, recollect that you used the aspnet_regsql.exe tool to configure a database to have the required tables. You then used web.config to configure membership, role and profile providers.

Note:
There are many interfaces that are implemented by the above mentioned classes. Since this article aims at quickly showing you how to implement security based on ASP.NET Identity from the ground up, these interfaces are not discussed here.

Using ASP.NET Identity

Now that you have some idea about ASP.NET Identity, let’s build an application step-by-step that shows how to implement security using ASP.NET Identity. Begin by creating a new ASP.NET Web Application using Visual Studio 2013. Make sure to select the Empty project template and check the MVC references checkbox.

Get Required NuGet Packages

The first step is to obtain the latest NuGet packages for ASP.NET Identity. Right click on the References folder and select the Manage NuGet Packages option. Search for “ASP.NET Identity” in the Manage NuGet Packages dialog. The following figure shows the NuGet package to be added.

The NuGet Package to be Added
The NuGet Package to be Added

This will add references to various OWIN and ASP.NET Identity assemblies. You can have a look at them by expanding the References folder or by checking the Installed packages in the same dialog (see below).

Manage NuGet Packages
Manage NuGet Packages

Creating Custom DbContext, User and Role

In this section you will create three POCOs that represent a custom DbContext, a custom user and a custom role respectively. So, add three POCOs to your application as shown below:

public class MyIdentityDbContext : IdentityDbContext<MyIdentityUser>
{
    public MyIdentityDbContext() : base("connectionstring")
    {

    }
}

public class MyIdentityUser : IdentityUser
{
    public string FullName { get; set; }
    public DateTime BirthDate { get; set; }
    public string Bio { get; set; }
}

public class MyIdentityRole:IdentityRole
{
    public MyIdentityRole()
    {

    }

    public MyIdentityRole(string roleName,string description) : base(roleName)
    {
        this.Description = description;
    }

    public string Description { get; set; }
}

The MyIdentityDbContext class inherits from the IdentityDbContext base class and specifies a generic type of MyIdentityUser. This way the underlying system can determine the table schema of the tables. Notice that the MyIdentityDbContext class constructor passes a connection string name – connectionstring – to the base class. This connection string is defined in web.config as follows:

<connectionStrings>
  <add name="connectionstring" connectionString="data source=.;initial catalog=Northwind;integrated security=true" providerName="System.Data.SqlClient" />
</connectionStrings>

Note that the above connection string specifies the target database as Northwind so that all the required tables will be created inside the existing database (Northwind in this case).

The MyIdentityUser class inherits from the IdentityUser base class and adds three properties – FullName, BirthDate and Bio. These properties make  the profile information of the user. The IdentityUser base class provides several properties such as UserName, Email and PasswordHash.

The MyIdentityRole class inherits from the IdentityRole base class and adds the Description property.

Adding an OWIN Startup Class

Now add an OWIN startup class in the App_Start folder using the OWIN Startup Class template. The following figure shows this template in the Add New Item dialog.

Add New Item
Add New Item

Change the name of the class file to Startup.cs and click Add. Then write the following code in the Startup class.

using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.AspNet.Identity;

[assembly: OwinStartup(typeof(AspNetIdentityDemo.App_Start.Startup))]

namespace AspNetIdentityDemo.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            CookieAuthenticationOptions options = new CookieAuthenticationOptions();
            options.AuthenticationType =  DefaultAuthenticationTypes.ApplicationCookie;
            options.LoginPath = new PathString("/account/login");
            app.UseCookieAuthentication(options);
        }
    }
}

Ensure that the namespaces as listed above are imported before you write any code. The assembly level attribute – OwinStartup – specifies an OWIN startup class. In this case it is AspNetIdentityDemo.App_Start.Startup. The Startup class consists of Configuration() method and receives a parameter of type IAppBuilder. We won’t go into the details of OWIN here. Suffice it to say that Configuration() method configures the authentication scheme. In this case the code uses cookie based authentication. The login page of the application is set to /account/login. You will create the Account controller in the following sections.

Creating View Model Classes

In this section you will create model classes need by the Account controller. In all you need four model classes – Register, Login, ChangePassword and ChangeProfile. These model classes are POCOs with some data annotations added to them. They are shown below:

public class Register
{
    [Required]
    public string UserName { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
    [Required]
    [EmailAddress]
    public string Email { get; set; }
    public string FullName { get; set; }
    public DateTime BirthDate { get; set; }
    public string Bio { get; set; }
}
public class Login
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}
public class ChangePassword
{
    [Required]
    public string OldPassword { get; set; }
    [Required]
    [StringLength(40, MinimumLength = 6,ErrorMessage = "Password must be between 6-40 characters.")]
    public string NewPassword { get; set; }
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmNewPassword { get; set; }
}
public class ChangeProfile
{
    public string FullName { get; set; }
    public DateTime BirthDate { get; set; }
    public string Bio { get; set; }
}

The Register, Login, ChangePassword and ChangeProfile model classes are quite straightforward and hence we won’t go into any detailed explanation. Create these classes and make sure to place them in the Models folder.

Creating AccountController

In this section you will create the AccountController – the controller where all the security related magic happens. The Account controller contains nine action methods and a constructor. The names and purpose of each of these methods is listed in the following table for your quick reference.

Method Description
AccountController() This is the constructor of the Account controller and initializes UserManager and RoleManager for further use.
Register() The Register() action method returns Register view to the user.
Register(Register model) This version of Register() is called when the user submits the registration form and does the job of creating a user account.
Login() The Login() action method returns Login view to the user.
Login(Login model) This version of Login() is called with the user submits the login form and does the job of authenticating a user.
ChangePassword() The ChangePassword() method returns ChangePassword view to the user.
ChangePassword(ChangePassword model) This version of ChangePassword() is called when the user submits the change password form and does the job of changing the user password.
ChangeProfile() The ChangeProfile() method returns ChangeProfile view to the user.
ChangeProfile(ChangeProfile model) This version of ChangeProfile() is called when the user submits the change profile form and does the job of changing the user profile information.
Logout() The Logout() method is called when a logged-in user clicks Logout button from any of the views and does the job of removing the authenticating cookie.

Now that you have some idea about the AccountController, let’s write these methods one by one. So, add the AccountController controller class in the Controllers folder and write its constructor as shown below:

private UserManager<MyIdentityUser> userManager;
private RoleManager<MyIdentityRole> roleManager;

public AccountController()
{
    MyIdentityDbContext db = new MyIdentityDbContext();

    UserStore<MyIdentityUser> userStore = new UserStore<MyIdentityUser>(db);
    userManager = new UserManager<MyIdentityUser>(userStore);

    RoleStore<MyIdentityRole> roleStore = new RoleStore<MyIdentityRole>(db);
    roleManager = new RoleManager<MyIdentityRole>(roleStore);

}

The above code declares two member variables inside the AccountController class – one of type UserManager and the other of type RoleManager. Notice that while declaring these variables, the generic type of MyIdentityUser and MyIdentityRole is specified.

The AccountController() constructor creates an instance of our custom DbContext class and passes it to the constructor of UserStore and RoleStore classes. The UserStore and RoleStore instances are further passed to the constructors of UserManager and RoleManager classes respectively. The UserStore and RoleStore classes basically perform database storage and retrieval tasks.

Next, add both the Register() methods as shown below:

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

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(Register model)
{
    if (ModelState.IsValid)
    {
        MyIdentityUser user = new MyIdentityUser();

        user.UserName = model.UserName;
        user.Email = model.Email;
        user.FullName = model.FullName;
        user.BirthDate = model.BirthDate;
        user.Bio = model.Bio;

        IdentityResult result = userManager.Create(user, model.Password);

        if (result.Succeeded)
        {
            userManager.AddToRole(user.Id, "Administrator");
            return RedirectToAction("Login","Account");
        }
        else
        {
            ModelState.AddModelError("UserName", "Error while creating the user!");
        }
    }
    return View(model);
}

The POST version of Register() method creates an instance of MyIdentityUser class and sets its properties to the corresponding properties of the Register model class. It then attempts to create a new user account by calling Create() method on the UserManager object. If IdentityResult.Succeeded returns true, it indicates that a user account has been successfully created. If so the newly created user is assigned an Administrator role (in a more realistic situation you will have a separate user-role management page where users are assigned roles. Here, for the sake of simplicity you are assigning a role at the time of registration itself.). The user is then redirected to the login page.

If there is some error while creating a user an error message is added to the ModelState dictionary and Register view is displayed again with the error messages.

Now, add Login() action methods as shown below:

public ActionResult Login(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(Login model, string returnUrl)
{
    if (ModelState.IsValid)
    {

        MyIdentityUser user = userManager.Find(model.UserName, model.Password);
        if (user != null)
        {
            IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
            authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
            AuthenticationProperties props = new AuthenticationProperties();
            props.IsPersistent = model.RememberMe;
            authenticationManager.SignIn(props, identity);
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }
    return View(model);
}

If a user tries to access a URL without logging in, he is redirected automatically to the login page. While doing so the system passes the URL of the page originally requested by the user in a returnUrl query string parameter. This URL is received in the Login() methods as returnUrl parameter. The first Login() method simply passes the returnUrl to the view so that it can be resent upon form submission.

The second Login() method validates whether user name and password are correct. This is done by finding a user with a specified user name and password using the UserManager object. If a user is found that indicates that user name and password are matching. If so, the code retrieves an authentication manager by calling HttpContext.GetOwinContext().Authentication and stores in a variable of type IAuthenticationManager. The user is logged out from any external logins by calling SignOut() method. Then the ClaimsIdentity object is created by calling CreateIdentity() method on the User Manager. The SignIn() method accepts this ClaimsIdentity and does the job of issuing an authentication cookie that indicates that a user is successfully logged in to the system. The AuthenticationProperties object specifies the IsPersistent property to indicate whether the authentication cookie should be a persistent cookie (true) or not (false).

Next, add ChangePassword() methods as shown below:

[Authorize]
public ActionResult ChangePassword()
{
    return View();
}

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult ChangePassword(ChangePassword model)
{
    if (ModelState.IsValid)
    {
        MyIdentityUser user = userManager.FindByName(HttpContext.User.Identity.Name);
        IdentityResult result = userManager.ChangePassword(user.Id, model.OldPassword, model.NewPassword);
        if(result.Succeeded)
        {
            IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
            authenticationManager.SignOut();
            return RedirectToAction("Login", "Account");
        }
        else
        {
            ModelState.AddModelError("", "Error while changing the password.");
        }
    }
    return View(model);
}

The second ChangePassword() method retrieves the current user name using HttpContext.User.Identity.Name. Based on this value, FindByName() method of the UserManager is called to retrieve the associated MyIdentityUser. Then ChangePassword() method is called on the UserManager by passing the Id of the user, old password and the new password. If the password change operation is successful the user is signed out of the system and is redirected to the login page.

Now, add ChangeProfile() methods as shown below:

[Authorize]
public ActionResult ChangeProfile()
{
    MyIdentityUser user = userManager.FindByName(HttpContext.User.Identity.Name);
    ChangeProfile model = new ChangeProfile();
    model.FullName = user.FullName;
    model.BirthDate = user.BirthDate;
    model.Bio = user.Bio;
    return View(model);
}

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult ChangeProfile(ChangeProfile model)
{
    if (ModelState.IsValid)
    {
        MyIdentityUser user = userManager.FindByName(HttpContext.User.Identity.Name);
        user.FullName = model.FullName;
        user.BirthDate = model.BirthDate;
        user.Bio = model.Bio;
        IdentityResult result = userManager.Update(user);
        if(result.Succeeded)
        {
            ViewBag.Message = "Profile updated successfully.";
        }
        else
        {
            ModelState.AddModelError("", "Error while saving profile.");
        }
    }
    return View(model);
}

The first ChangeProfile() method retrieves MyIdentityUser using the FindByName() method of the UserManager. The current user’s profile details are filled in ChangeProfile model and passed to the ChangeProfile view. The second ChangeProfile() method receives the modified user information. It then retrieves the current user using the FindByName() method of UserManager. The existing user information such as FullName, BirthDate and Bio is updated with the new information and to persist the changes, Update() method of UserManager is called.

Now add the final action method – Logout() – as shown below:

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult LogOut()
{
    IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
    authenticationManager.SignOut();
    return RedirectToAction("Login", "Account");
}

The Logout() method retrieves the authentication manager using HttpContext.GetOwinContext().Authentication property and calls its SignOut() method. Doing so will delete the authentication cookie. The user is then redirected to the login page.

This completes the AccountController. 

Creating Register, Login, ChangePassword and ChangeProfile Views

You will need to create four views – Register.cshtml, Login.cshtml, ChangePassword.cshtml and ChangeProfile.cshtml – for the corresponding action methods of the AccountController. We will not go into the details of these views here because they are quite straight forward. You can grab them from the code download of this article. 

Creating HomeController

In this section you will create HomeController – the controller whose action methods are to be secured. So, add HomeController to the Controllers folder and modify its Index() action method as shown below:

[Authorize]
public ActionResult Index()
{
    MyIdentityDbContext db = new MyIdentityDbContext();

    UserStore<MyIdentityUser> userStore = new UserStore<MyIdentityUser>(db);
    UserManager<MyIdentityUser> userManager = new UserManager<MyIdentityUser>(userStore);

    MyIdentityUser user = userManager.FindByName(HttpContext.User.Identity.Name);

    NorthwindEntities northwindDb = new NorthwindEntities();
    List<Customer> model = null;

    if(userManager.IsInRole(user.Id, "Administrator"))
    {
        model = northwindDb.Customers.ToList();
    }

    if(userManager.IsInRole(user.Id, "Operator"))
    {
        model = northwindDb.Customers.Where(c => c.Country == "USA").ToList();
    }

    ViewBag.FullName = user.FullName;

    return View(model);
}

Notice that the Index() action method is decorated with [Authorize] attribute because we wish to secure this action method. Inside, it creates MyIdentityDbContext, UserStore and UserManager as before. It then calls FindByName() method of the UserManager to retrieve the currently logged-in user. To check whether a user belongs to the Administrator role or not the IsInRole() method of UserManager is used. Based on the outcome of IsInRole() method all customers are retrieved or only the customers belonging to the USA are retrieved (it is assumed that you have created the EF data model for the Customers table of the Northwind database). This data is passed to the Index view. The User’s FullName is also passed to the Index view through the FullName ViewBag property.

Creating Index View

The Index view is a simple view that displays a welcome message to the user using the FullName ViewBag property. It also displays a table of Customer records. We won’t discuss the Index view here. You can get it from the source code download of this article.

Creating Roles in the System

Although we used Administrator and Operator roles in our code, we haven’t defined them yet. This task is to be done inside the Application_Start event of Global.asax. The following code shows how this can be done:

MyIdentityDbContext db = new MyIdentityDbContext();
RoleStore<MyIdentityRole> roleStore = new RoleStore<MyIdentityRole>(db);
RoleManager<MyIdentityRole> roleManager = new RoleManager<MyIdentityRole>(roleStore);

if (!roleManager.RoleExists("Administrator"))
{
    MyIdentityRole newRole = new MyIdentityRole("Administrator", "Administrators can add, edit and delete data.");
    roleManager.Create(newRole);
}

if (!roleManager.RoleExists("Operator"))
{
    MyIdentityRole newRole = new MyIdentityRole("Operator", "Operators can only add or edit data.");
    roleManager.Create(newRole);
}

The above code creates a RoleStore and a RoleManager. The RoleExists() method of RoleManager is used to determine if a role already exists. If the role doesn’t exist, a new MyIdentityRole instance is created by passing a role name and its description. The role is created in the system by calling the Create() method of the RoleManager and passing the MyIdentityRole object as a parameter.

Testing the Application

Now that you have completed all the parts of the sample application, it’s time to test the application. Be on the Index view and press F5 to run the application. You will find that you are automatically taken to the login page (/account/login). Click on the Register a new user link from the page so as to display the registration page as shown below:

Registration Page
Registration Page

Enter all the registration information and click on the Register button to create a new user. After successful user creation you will be taken to the login page (see below).

Login Page
Login Page

Enter user name and password and click on the Login button. You will be shown the Index view with a welcome message and Customer data from the Northwind database:

Welcome Message and Customer Data
Welcome Message and Customer Data

Go ahead and also test Change Password and Modify Profile functionality. 

Summary

ASP.NET Identity offers a new way of authenticating users of your web applications. It is more flexible and powerful than the ASP.NET membership system. This article showed how to implement security using ASP.NET Identity in an ASP.NET MVC application from the ground up. The example developed in this article covers user registration, login, logout, change password and change profile functionality. Once you master these basics you can go ahead and add more advanced features such as external logins and two factor authentication.

Extra Reading Links

The post Securing ASP.NET MVC Applications with ASP.NET Identity appeared first on CodeGuru.

]]>
Using Display Templates and Editor Templates in ASP.NET MVC https://www.codeguru.com/dotnet/using-display-templates-and-editor-templates-in-asp-net-mvc/ Wed, 06 Aug 2014 07:01:00 +0000 https://www.codeguru.com/uncategorized/using-display-templates-and-editor-templates-in-asp-net-mvc/ Introduction to MVC Editor Templates ASP.NET MVC developers often use HTML helpers such as LabelFor() and TextBoxFor() to display model properties on a view. Although this approach works fine in many situations, it proves to be inadequate when you wish to customize how data is presented to the user for displaying and for editing. Luckily, […]

The post Using Display Templates and Editor Templates in ASP.NET MVC appeared first on CodeGuru.

]]>
Introduction to MVC Editor Templates

ASP.NET MVC developers often use HTML helpers such as LabelFor() and TextBoxFor() to display model properties on a view. Although this approach works fine in many situations, it proves to be inadequate when you wish to customize how data is presented to the user for displaying and for editing. Luckily, you can use display templates and editor templates to overcome this limitation. This article discusses what display templates and editor templates are and how to use them in an ASP.NET MVC application.

What Are MVC Display Templates and Editor Templates?

When you an HTML helper, such as LabelFor() or TextBoxFor(), it displays a model property in a fixed manner. For example, LabelFor() renders a model property name in a <label> tag and TextBoxFor() renders a textbox in which a model property is shown for editing. Although this arrangement works fine in many cases, at times you need more control over the way data is shown to the end user. Consider, for example, that you have a model property that represents currency. While displaying this property value to the end user, you want to show a currency symbol such as $ along with the property value. Such a customization is not possible with the above-mentioned HTML helpers. Another example could be a DateTime model property that needs to be displayed in a specific custom format.

Luckily, ASP.NET MVC comes with templated helpers that can be used in such cases. The following MVC editor templates are available:

  • DisplayFor()
  • DisplayForModel()
  • EditorFor()
  • EditorForModel()

The DisplayFor() helper displays a model property using what is known as a Display Template. A display template is simply a user interface template that is used to display a model property. If no custom display template is provided by developers, a default one is used. The DisplayForModel() helper is similar to DisplayFor() but displays the whole model (not just a single property) using a display template. The EditorFor() helper displays a user interface for editing a model property. This user interface is known as Editor Template. The EditorForModel() helper displays the whole model for editing using a given editor template. All the helpers listed above pick a template based on the data type of a model property.

When creating views, you can use DisplayFor(), DisplayForModel(), EditorFor(), and EditorForModel() helpers even if you don’t intend to have a customized user interface. Later, if you decide to have a customized interface, all you need to do is define the display and editor templates.

Just to get an idea of how these helpers work, look at the following figure:

Display Helper
Display Helper

The preceding figure shows a model property named BirthDate (System.DateTime) displayed using a custom display template and editor template respectively. This user interface is the result of the following view code :

@Html.DisplayFor(model => model.BirthDate)
@Html.EditorFor(model => model.BirthDate)

Creating and Using Display Templates

Now that you know what display and editor templates are, let’s begin with an example of creating a custom display template. Create a new ASP.NET MVC application (Empty project template) and add Entity Framework Data Model for the Employees table of Northwind database. This model is shown in the following figure:

Entity Framework Data Model
Entity Framework Data Model

Then, add HomeController and Index view to the project. Next, add the following code in the Index() action method.

public ActionResult Index()
{
    NorthwindEntities db=new NorthwindEntities();
    Employee emp = db.Employees.Find(1);
    return View(emp);
}

The preceding code retrieves an Employee from the database whose EmployeeID is 1. It then passes this Employee object to the Index view. The Index view contains the following markup:

@model DisplayEditorTemplatesDemo.Models.Employee

@{
    Layout = null;
}
...
<body>
    @using(Html.BeginForm())
    {
        @Html.DisplayFor(m=>m.EmployeeID)
        @Html.DisplayFor(m=>m.FirstName)
        @Html.DisplayFor(m=>m.BirthDate)
    }
</body>
</html>

The Index view sets the model for the view to be Employee class. It then uses the DisplayFor() helper to show three model properties: EmployeeID, FirstName, and BirthDate.

At this stage, you haven’t defined any custom display templates. If you run the application, you will find that the DisplayFor() helper uses default templates to output the model properties, as shown in the following figure:

Default Template
Default Template

Now, let’s define some custom templates. To do so, create a Shared sub-folder under the Views folder. Then, add a DisplayTemplates sub-folder inside the Shared folder. Remember that this folder name must be DisplayTemplates. As mentioned earlier, the DisplayFor() helper looks for custom display templates inside this folder based on the data type of a model property being displayed. In the previous example, the EmployeeID, FirstName, and BirthDate properties are of type Int32, String, and DateTime respectively.

To create custom display templates, add three partial views to the DisplayTemplates folder and name them Int32.cshtml, String.cshtml, and DateTime.cshtml, respectively. Remember that the names of these display template files must reflect the data types they deal with.

Then, add the following code to the Int32.cshtml file:

@model Int32

<h1>#@Model</h1>

As you can see, this display template sets its model to be Int32. It then renders the Model property in the <h1> tag and attaches # at the beginning of the value. On the same lines, create String.cshtml and DateTime.cshtml as shown:

String.cshtml
=============

@model String

<strong>@Model</strong>
DateTime.cshtml
===============

@model DateTime

<strong>@Model.ToString("dd MMM yyyy")</strong>

Notice how the string data is being rendered by using the <string> tag and how the DateTime data is being formatted by using the dd MMM yyyy format.

If you run the application again, you will see the following in the browser:

dd MMM yyyy format
dd MMM yyyy format

Remember that once the templates are created, all the model properties of Int32 type will start using the custom display template. The same holds true for String and DateTime model properties.

Creating and Using Editor Templates

Now, let’s create a custom editor template for the DateTime data type. To do so, create an EditorTemplates sub-folder under the Shared folder and add a DateTime.cshtml file there. This process is quite similar to what you did for creating display templates. Then, add the following code to the DateTime.cshtml editor template:

@model DateTime

@{
    List<SelectListItem> days = new List<SelectListItem>();
    for (int i = 1; i <= 31;i++ )
    {
        days.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString(), Selected = (i == Model.Day ? true : false) });
    }

    List<SelectListItem> months = new List<SelectListItem>();
    for (int i = 1; i <= 12; i++)
    {
        months.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString(), Selected = (i == Model.Month ? true : false) });
    }

    List<SelectListItem> years = new List<SelectListItem>();

    int prevYearCount = ViewBag.PreviousYearCount;
    int nextYearCount = ViewBag.NextYearCount;

    for (int i = Model.Year - prevYearCount; i <= Model.Year + nextYearCount; i++)
    {
        years.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString(), Selected = (i == Model.Year ? true : false) });
    }
}

@Html.DropDownList("days", days)
@Html.DropDownList("months", months)
@Html.DropDownList("years", years)

The preceding code basically renders three DropDownLists for selecting day, month, and year, respectively. The three for loops create generate a List of SelectListItem objects that contain days, months, and years, respectively. Notice how the default selection in these dropdownlists is made using the current model value and Selected property.

The year dropdownlist contains a certain number of years from the past and future. These offsets are passed from the view using the PreviousYearCount and NextYearCount ViewData / ViewBag properties.

To display the BirthDate model property using the editor template you just created, add the following code to the Index view.

@Html.EditorFor(m => m.BirthDate, new { PreviousYearCount = 10, NextYearCount = 10 })

As you can see, the preceding code uses an EditorFor() helper to show an editor for the BirthDate property. Notice how the PreviousYearCount and NextYearCount values are passed as an anonymous object. These properties are translated to equivalent ViewData entries and are accessible inside the editor template (as you did in the editor template code earlier).

If you run the application, you will see this:

The BirthDate Model Property
The BirthDate Model Property

Using DisplayForModel() and EditorForModel()

The DisplayFor() and EditorFor() helpers work for a single model property. At times, you need to render a user interface for the whole model. For example, you may have a model property that is of a complex type (say, a property that is of type Address). In such cases, you can use the DisplayForModel() and EditorForModel() helpers. These helpers pick display and editor templates based on the model type. If no template is found, they use a default template.

To see DisplayForModel() and EditorForModel() in action, add Employee.cshtml in both the folders—DisplayTemplates and EditorTemplates. Add the following markup in the Employee.cshtml from the DisplayTemplates folder:

@model DisplayEditorTemplatesDemo.Models.Employee

<table border="1" cellpadding="10">
    <tr>
        <td>Employee ID :</td>
        <td>@Model.EmployeeID</td>
    </tr>
    <tr>
        <td>First Name :</td>
        <td>@Model.FirstName</td>
    </tr>
    <tr>
        <td>Last Name :</td>
        <td>@Model.LastName</td>
    </tr>
    <tr>
        <td>Birth Date :</td>
        <td>@Html.DisplayFor(m => m.BirthDate)</td>
    </tr>
</table>

The preceding template has Employee as its model and displays the EmployeeID, FirstName, LastName, and BirthDate model properties. Notice how DisplayFor() is used to display the BirthDate property (and we have a custom template for DateTime properties).

Add the following code in the Employee.cshtml file from the EditorTemplates folder.

@model DisplayEditorTemplatesDemo.Models.Employee

<table border="1" cellpadding="10">
    <tr>
        <td>Employee ID :</td>
        <td>@Html.EditorFor(m=>m.EmployeeID)</td>
    </tr>
    <tr>
        <td>First Name :</td>
        <td>@Html.EditorFor(m => m.FirstName)</td>
    </tr>
    <tr>
        <td>Last Name :</td>
        <td>@Html.EditorFor(m => m.LastName)</td>
    </tr>
    <tr>
        <td>Birth Date :</td>
        <td>@Html.EditorFor(m => m.BirthDate)</td>
    </tr>
</table>

The previous code uses the DisplayFor() and EditorFor() helpers to render EmployeeID, FirstName, LastName, and BirthDate, respectively.

After creating the preceding templates, add the following code to the Index view.

@Html.DisplayForModel()
@Html.EditorForModel(new { PreviousYearCount = 10, NextYearCount = 10 })

Notice that the EditorForModel() helper passes an anonymous object because our custom DateTime template needs that.

If you run the application, you should see something like this:

EditorForModel()
EditorForModel()

The UIHint Attribute

When you create a display template or editor template for a data type, all the model properties of that data type start using it. At times, you may want some of the model properties of the said data type to use some different templates. You can hint your intention by using the [UIHint] attribute. The [UIHint] attribute needs to be added to the model property. To see how [UIHint] works, create another display template called DateTime2.cshtml and write the following code in it:

@model DateTime

<strong>@Model.ToString("dd / MM / yyyy")</strong>

This code displays the date in dd / MM / yyyy format instead of dd MMM yyyy format.

Now, add a metadata class for the Employee model class as shown:

public class EmployeeMetadata
{
    [UIHint("DateTime2")]
    public DateTime BirthDate { get; set; }

}

[MetadataType(typeof(EmployeeMetadata))]
public partial class Employee
{

}

Note how the [UIHint] attribute has been added to the BirthDate property. The [UIHint] attribute specifies that the DateTime2 template is to be used for this model property. If you run the application, you will see the BirthDate property being displayed like this:

BirthDate Property
BirthDate Property

Summary

Display templates and editor templates allow you to display model properties using a custom UI template. The DisplayFor(), DisplayForModel(), EditorFor(), and EditorForModel() helpers pick display / editor templates based on the data type of a model property. Custom display / editor templates are .cshtml files that you place inside DisplayTemplates and EditorTemplates folders under the Views > Shared folder. Together, they provide a flexible way to display or edit model properties as compared to helpers such as LabelFor() and TextBoxFor().

Extra Reading Links

The post Using Display Templates and Editor Templates in ASP.NET MVC appeared first on CodeGuru.

]]>
Overview of OWIN and Katana https://www.codeguru.com/dotnet/overview-of-owin-and-katana/ Fri, 11 Jul 2014 07:01:00 +0000 https://www.codeguru.com/uncategorized/overview-of-owin-and-katana/ Introduction As OWIN is becoming popular and more common, it is important for ASP.NET developers to understand what OWIN and Katana are. ASP.NET Web API and ASP.NET Identity are already geared towards using these specifications. To that end this article explains what OWIN and Katana are and how they fit into the whole web development […]

The post Overview of OWIN and Katana appeared first on CodeGuru.

]]>
Introduction

As OWIN is becoming popular and more common, it is important for ASP.NET developers to understand what OWIN and Katana are. ASP.NET Web API and ASP.NET Identity are already geared towards using these specifications. To that end this article explains what OWIN and Katana are and how they fit into the whole web development picture for ASP.NET developers. You will also develop a simple application to get a code level understanding of these features.

Background

The .NET framework made its appearance sometime in 2002. ASP.NET was bundled as a part of the overall .NET framework. The idea was to provide a unified development framework for building desktop and web applications and services. In those days Windows development tools such as VB6 were common and popular. Naturally, ASP.NET and Visual Studio attempted to provide a RAD (Rapid Application Development) development environment to web developers. Web pages were looked upon as Web Forms backed by a rich server side Page framework. ASP.NET also offered plenty of Server Controls to develop rich user interface elements quickly. Web Forms provided its core functionality through server side events. Developers housed server controls (such as a Button, TextBox and GridView) on a web form and then handled their server side events (such as Click and SelectedIndexChanged). Features such as ViewState and Data Binding were added to make the programing model closer to the desktop application programming model.

Although the Web Forms framework served well for many years, it has its own limitations. The Web Forms framework was a part of the overall .NET framework. This bundling required that the ASP.NET and the .NET framework be released together. It became difficult for Web Forms framework to keep pace with the dynamic and rapidly changing web development trends and needs.

All the Web Forms applications make use of System.Web – the core assembly providing ASP.NET functionality. The System.Web assembly provides a rich set of functionality to web developers. However, the problem is that many times you may use only a small portion of this functionality but you still need to refer to the whole assembly. This is unnecessary and resource consuming. Moreover, System.Web is tightly coupled with IIS. That means your ASP.NET applications can run only on IIS.

The following figure summarizes what we discussed so far.

ASP.NET Application
ASP.NET Application

Over the years the way web applications are built and used has changed. Modern web applications are standards based, lightweight, modular and greatly rely on features such as Ajax for communicating with the server. Considering the above limitations it is difficult for the Web Forms framework to effectively meet the requirements of modern web development. That’s why Microsoft decided to introduce OWIN and Katana into ASP.NET development.

What is OWIN?

OWIN stands for Open Web Interface for .NET. OWIN is a specification that describes how web development frameworks such as ASP.NET MVC should interact with the web servers. The goal of OWIN is to decouple web applications from the web server by introducing an abstraction layer. Such an abstraction enables you to run the same application on all the web servers that support OWIN. Additionally, it simplifies the overall system because the abstraction layer can provide a lightweight infrastructure to host the applications. IIS provides a rich set of features to the web applications. However, web applications may not need all these features. It might be sufficient for them to have minimal HTTP processing capabilities. OWIN compatible host can provide such a hosting environment to these applications. Moreover, you can define a pipeline of modules that are used during the request processing. An OWIN pipeline is a chain of OWIN compatible components through which a request passes.

The OWIN specification is a community initiative and more details can be found at the owin.org website.

What is Katana?

Katana is a set of components by Microsoft built using OWIN specifications. Some of these components include Web API, ASP.NET Identity and SignalR. The following figure shows the overall architecture of a Katana based application.

Overall architecture of a Katana based application
Overall architecture of a Katana based application

As you can see from the figure, there are four layers namely Application, Middleware, Server and Host. Let’s understand the job of each of these layers.

The Application layer indicates your client application. For example, a web site developed in ASP.NET MVC. It could also be a Windows based application or even a console application. This application is used by the end users and it need not do anything special as far as OWIN is concerned.

The middleware layer indicates a set of components built using OWIN specifications. These components can be larger frameworks such as Web API or specialized components such as ASP.NET Identity or SignalR. There can be more than one component in this layer. If so, they can form a pipeline – a chain of components – that is executed before the request reaches the server. You can add or remove the components from this chain through your code.

The third layer is Server. A server listens to an incoming request and performs the relevant network level tasks such as opening a socket. Katana comes with two server components:

  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Host.HttpListener

The SystemWeb host hooks into IIS through an HTTP handler and module. This should be used if you wish to use IIS as your host. The latter is lightweight server developed using .NET framework’s HttpListener class and it is the default in case you decide to create your own host (self-hosting).

The final layer is Host. This layer creates and manages a process for your application. It also provides the overall environment for your application. There are three options for hosting applications based on Katana:

  • IIS
  • OwinHost.exe
  • Custom host

The first option uses IIS as the host. Notice that IIS acts as a host as well as a server. The OwnHost.exe is a readymade lightweight host that you can use to host your applications. If these two options do not meet your requirements you can always create a custom host.

Developing a Simple Application Using OWIN

In this section you will develop a simple application using Katana architecture as discussed earlier. This application consists of the layers discussed above and consists of three main pieces:

  • Windows Forms application that acts as a server and host
  • Web API for retrieving Customer information from the Northwind database
  • Windows Forms application that acts as a client to the Web API

The Web API is bundled in the same project as the Windows Forms host but you can also create it as a separate Class Library type of project if you wish. The following figure shows how the host Windows Forms application looks:

OWIN Self Host Application
OWIN Self Host Application

As you can see the host application consists of a Start button. Clicking on the Start button generates a random port number between 8000 – 9999 and starts an OWIN host at the specified port. The base URL of the host is displayed in a Label control. Closing the form terminates the host.

The client application that calls the Web API is shown below:

Client Application
Client Application

The client application consists of two textboxes and a button. The textboxes are used to specify the port number (as generated and seen in the host application) and a CustomerID respectively. Clicking on the “Call Web API” button invokes the Web API and retrieves the CompanyName of the specified CustomerID. The CompanyName is then displayed in a Label as shown.

The aim of this example is to give you a broad idea of how the OWIN concepts that we have discussed so far look like at code level. Any detailed discussion of the code and classes involved in the example is beyond the scope of this article. So, let’s get going!

Creating the Host Application

Begin by creating a new Windows Forms project in Visual Studio and name the project MySelfHost. Then right click on the References folder and select “Manage NuGet Packages” option. Using the Manage NuGet Packages dialog add a NuGet package for Microsoft ASP.NET Web API 2.1 OWIN Self Host. The following figure shows this package in the dialog.

NuGet package for Microsoft ASP.NET Web API 2.1 OWIN Self Host
NuGet package for Microsoft ASP.NET Web API 2.1 OWIN Self Host

We need this package because it allows you to self host Web API in your own application (Windows Forms application in this case). Adding this package will also add several other dependencies and you can have a look at them using the Installed Packages section of the same dialog (or expand the References folder to have a glance at the new assemblies that get added).

Then add a new class to the project based on the OWIN Startup Class template. The following figure shows this template in Add New Item dialog of Visual Studio:

Add New Item
Add New Item

Name the class as Startup.cs. Once added, import the following namespaces in the Startup.cs file.

using Microsoft.Owin;
using Owin;
using System.Web.Http;

Then add the following code to the Startup class:

[assembly: OwinStartup(typeof(MySelfHost.Startup))]
 
namespace MySelfHost
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "DefaultWebApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            app.UseWebApi(config);
        }
    }
}

Notice that the above code uses an assembly level attribute – OwinStartup to specify the Startup class as an OWIN startup class. The Startup class has a method named Configuration() that is responsible for configuring an OWIN application. In this case the HttpConfiguration object defines a default route for Web API requests and then uses UseWebApi() extension method. The UseWebApi() method indicates that we intend to use the Web API framework as an OWIN middleware component. Note that the startup class name need not be Startup as it is configurable through the [OwinStartup] attribute but whatever startup class you create must contain the Configuration() method.

Next, design the Windows Form as shown above (see the figure for Self Host application earlier). Then go in the Windows Forms code editor and import the following namespace:

using Microsoft.Owin.Hosting;

Now add the following code in the Click event of the Start button.

private void button1_Click(object sender, EventArgs e)
{
    Random r = new Random();
    int portNumber = r.Next(8000, 9999);
    string baseUrl = "http://localhost:" + portNumber;
    WebApp.Start<Startup>(baseUrl);
    label1.Text = "OWIN Host Started at " + baseUrl;
}

The above code generates a random port number in the range of 8000-9999 using Random class. It then uses the WebApp.Start() method to start the OWIN host. Notice that the Start() method can also specify the OWIN startup class instead of the [OwinStartup] attribute (any one technique can be used although our code shows both the techniques).

That is all we need to do in order to create an OWIN host.

Creating the Web API

Now we need to create the Customer Web API itself. So, add a Models folder in the same Windows Forms project and add an Entity Framework Data Model for the Customers table to it. The following figure shows the Customer entity in the Visual Studio designer.

Customer Entity
Customer Entity

Next, add a new class to the same project and name it – CustomerController. This is your Web API controller class and is shown below:

namespace MySelfHost
{
    public class CustomerController:ApiController
    {
        public string GetCompanyName(string id)
        {
            NorthwindEntities db = new NorthwindEntities();
            Customer obj = db.Customers.Find(id);
            return obj.CompanyName;
        }
    }
}

The CustomerController class inherits from the ApiController base class (make sure you have imported System.Web.Http and MySelfHost.Models namespaces). It contains GetCompanyName() method that handles GET requests. The GetCompanyName() method accepts a CustomerID as its parameter. Inside, the method simply retrieves a Customer from the Customers DbSet and returns its CompanyName to the caller.

This completes the Web API.

Creating the Client Application

In this final step you will create a Windows Forms client that consumes the Web API hosted in our custom OWIN host. To develop this client application add another Windows Forms project (name it MyClient) to the same solution. Design the form as shown earlier (see the second figure at the beginning of this example). Then write the following code in the Click event handler of the “Call Web API” button.

private void button1_Click(object sender, EventArgs e)
{
    string baseUrl = "http://localhost:" + textBox2.Text;
    HttpClient client = new HttpClient();
    HttpResponseMessage response = client.GetAsync(baseUrl + "/api/customer/" + textBox1.Text).Result;
    label1.Text = response.Content.ReadAsStringAsync().Result;
}

The above code forms the base URL of the host by picking the port number from the textbox. It then creates an instance of HttpClient class (make sure you have referenced System.Net.Http assembly and have imported System.Net.Http namespace). It then makes a GET request to the Web API using the GetAsync() method. Notice that the GetAsync() method forms the complete URL by appending /api/customer/<customer_id>. The response from the Web API is received as HttpResponseMessage. To read the actual CompanyName, ReadAsStringAsync() method is used.

This completes the client application.

Running the Application

Now that you have built all the parts of this example, it’s time to run and test the application. First of all, build the solution. Then run the MySelfHost project. Doing so will launch the host form. Click on the Start button so as to start the host. Note down the randomly generated port number from the base URL of the host. You will need this port number while running the client.

Then run the MyClient project. Enter the port number and a CustomerID in the respective textboxes and click on the “Call Web API” button. If all goes well you should see the CompanyName in the Label.

Summary

Open Web Interface for .NET or OWIN is a specification describing an abstraction that separates your application and the actual web server. Katana is a set of components developed by Microsoft based on the OWIN specifications. Using OWIN you can develop lightweight and modular applications with a possibility of porting them across different web servers. This article presented a quick overview of OWIN and Katana. You also developed a simple yet functional application that hosts Web API in a custom OWIN host.

Extra Reading Links

About the Author:

Bipin Joshi is an author and a .NET trainer who writes about apparently unrelated topics – yoga & technology! Bipin has been programming since 1995 and is working with .NET framework ever since its inception. He has authored or co-authored half a dozen books and numerous articles on .NET technologies. He has also penned a few books on Yoga. You can read more about him here.

The post Overview of OWIN and Katana appeared first on CodeGuru.

]]>