Monthly Archives: June 2015

Attribute Routing in ASP.NET MVC

With earlier version of ASP.NET MVC routing was strictly convention based and there was no way to give custom routes for specific controller and action associated with it. With ASP.NET MVC 5 and above attribute based routing feature was introduced. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web application. The earlier style of routing, called convention-based routing, is still supported and you can combine both techniques in the same controller and web application as well. To enable attribute routing, call MapMvcAttributeRoutes during configuration in RouteConfig.cs file

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapMvcAttributeRoutes();

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

Now in the controller as part of action we can declare custom routes for each and every action

public class HomeController : Controller
{
    [Route("Home/Test")]
    [Route("Home/Test1")]
    [Route("Home/Test2")]
    public ActionResult Index()
    {
        return View();
    }

    [Route("users/about")]
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";
        return View();
    }
}

You can set a common prefix for an entire controller by using the [RoutePrefix] attribute like show below

[RoutePrefix("Orders")]
public class HomeController : Controller
{
    [Route("Home/Test")]
    [Route("Home/Test1")]
    [Route("Home/Test2")]
    public ActionResult Index()
    {
        return View();
    }

    [Route("users/about")]
    public ActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";
        return View();
    }
}

When to use Attribute Routing
The convention-based routing is complex to support certain URI patterns that are common in RESTful APIs. But by using attribute routing you can define these URI patterns very easily. For example, resources often contain child resources like Clients have orders, movies have actors, books have authors and so on. It’s natural to create URIs that reflects these relations like as: /clients/1/orders. This type of URI is difficult to create using convention-based routing. Although it can be done, the results don’t scale well if you have many controllers or resource types. With attribute routing, it’s pretty much easy to define a route for this URI.

Similar attribute routing concept holds good for Web API 2

Advertisements

Explain Model Binding in ASP.NET MVC ?

Suppose you had an API like shown below

public class Person
{
    public string FirstName { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public int Id { get; set; }
}
public class PersonController : Controller
{
    [HttpPost]
    public ActionResult Update(Person person)
    { 
        //Do Some thing over here
    }
}

You can easily post a Person to that action method using JSON through $ajax using jQuery. But the bigger question is how ASP.NET MVC transforms the JSON payload or forms payload to required object. Under the hood, ASP.NET MVC uses the DefaultModelBinder in combination with the JsonValueProviderFactory to bind that value.Then question arises Why simply deserialize the incoming JSON request directly to the model (Person)? There are couple of ways in which data gets posted

    • application/x-www-form-urlencoded – When you submit a typical HTML form, the content type of that submission is application/x-www-form-url-encoded. the contents of the form is posted as a set of name value pairs separated by ampersand characters. The name and value within each pair are separated by an equals sign. When content is posted in this format, the DefaultModelBinder calls into the FormValueProvider asking for a value for each property of the model
    • application/json – Another content type in which u can post data is through JSON objects like shown below
      <script type="text/javascript">
          $(function () {
              var person = { FirstName: "Aamol", LastName: "Gote", Email: "a@gmail.com", Id: 1 }
              var personJSON = JSON.stringify(person);
              $.ajax({
                  url: '/Person/update',
                  type: 'POST',
                  dataType: 'json',
                  data: personJSON,
                  contentType: "application/json",
              });
          });
      </script>
      

      When this code executes, notice that the content is encoded as JSON rather than form url encoded. JSON is a serialization format so it’s in theory possible that we could straight deserialize that post to a Person instance, but ASP.NET MVC does not do that, reason for it is has to perform validation on input values, if it does not then the serialization would fail. Serialization is an all or nothing affair, when serialization fails, all you know is that the format didn’t match the type. You don’t have access to the granular details we need to provide property level validation.

So to solve this we really want is a way bind each property of the model one at a time so we can determine which of the fields are valid and which ones are in error. Fortunately, the DefaultModelBinder already knows how to do that when working with the dictionary-like IValueProvider interface. All the ket value pairs form-encoded and JSON are coverted to type IValueProvider (Dictionary) and DefaultModelBinder already knows how to bind those values to a type while providing property level validation.
Value providers provide an abstraction over where values actually come from. Value providers are responsible for aggregating the values that are part of the current request, e.g. from Form collection, the query string, JSON, etc. They basically say “I don’t know what a ‘FirstName’ is for or what you can do with it, but if you ask me for a ‘FirstName’ I can give you what I have.”
Model binders are responsible for querying the value providers and building up objects based on those results. They basically say “I don’t know where directly to find a ‘FirstName’, ‘LastName’, or ‘Age’, but if the value provider is willing to give them to me then I can create a Person object from them.”

Model binders aren’t locked to individual sources they can build objects from an aggregate of sources for e.g. if you person object is posted and a client makes a JSON POST request to an action method with the url /person/update/1 with the following content:

{ FirstName: "Aamol", LastName: "Gote", Email: "a@gmail.com"}

The DefaultModelBinder will pull the Id value from the RouteData and the FirstName, LastName and Email values from the JSON when building up the Person object. Afterwards, it’ll perform validation without having to know that the various values came from different sources.
In Summary – we use a value provider for JSON to enable property level validation of the incoming post and also so that model binding can build up an object by aggregating multiple sources of data without having to know anything about those sources.

Docker Containers

A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings. It is light weight self contained process, containers are isolated but share underlying OS. Containers are self-contained execution environments—with their own, isolated CPU, memory, block I/O, and network resources—that share the kernel of the host operating system. The result is something that feels like a virtual machine, but sheds all the weight and startup overhead of a guest operating system.

Containers and Virtual Machines
Containers are an abstraction at the app layer that packages code and dependencies together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space. Containers take up less space than VMs (container images are typically tens of MBs in size), and start almost instantly.

Virtual machines (VMs) are an abstraction of physical hardware turning one server into many servers. The hypervisor allows multiple VMs to run on a single machine. Each VM includes a full copy of an operating system, one or more apps, necessary binaries and libraries – taking up tens of GBs. VMs can also be slow to boot.

Docker is a software platform that allows you to build, test, and deploy applications quickly. Docker packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and run time. Using Docker, you can quickly deploy and scale applications into any environment and know your code will run.

The one big difference between containers and VMs is that containers *share* the host system’s kernel with other containers.

Docker uses Linux Kernel features like namespaces and control groups to create containers on top of an operating system.

Lightweight and Fast: Docker containers are very lightweight and fast. Since containers are just sandboxed environments running on the kernel, they take up fewer resources. You can create and run a Docker container in seconds, compared to VMs which might take longer because they have to boot up a full virtual operating system every time.

Ease of use: Docker has made it much easier for anyone — developers, systems admins, architects and others — to take advantage of containers in order to quickly build and test portable applications. It allows anyone to package an application on their laptop, which in turn can run unmodified on any public cloud, private cloud, or even bare metal. The mantra is: “build once, run anywhere.”

Docker Hub: Docker users also benefit from the increasingly rich ecosystem of Docker Hub, which you can think of as an “app store for Docker images.” Docker Hub has tens of thousands of public images created by the community that are readily available for use. It’s incredibly easy to search for images that meet your needs, ready to pull down and use with little-to-no modification.

Modularity and Scalability: Docker makes it easy to break out your application’s functionality into individual containers. For example, you might have your Postgres database running in one container and your Redis server in another while your Node.js app is in another. With Docker, it’s become easier to link these containers together to create your application, making it easy to scale or update components independently in the future.