Thursday, June 9, 2016

Building Your First Web API with ASP.NET Core MVC and Visual Studio

Building Your First Web API with ASP.NET Core MVC and Visual Studio

1461 of 1638 people found this helpful
By Mike Wasson and Rick Anderson
HTTP is not just for serving up web pages. It’s also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop apps.
In this tutorial, you’ll build a simple web API for managing a list of “to-do” items. You won’t build any UI in this tutorial.
ASP.NET Core has built-in support for MVC building Web APIs. Unifying the two frameworks makes it simpler to build apps that include both UI (HTML) and APIs, because now they share the same code base and pipeline.
Note
If you are porting an existing Web API app to ASP.NET Core, see Migrating from ASP.NET Web API

Overview

Here is the API that you’ll create:
API Description Request body Response body
GET /api/todo Get all to-do items None Array of to-do items
GET /api/todo/{id} Get an item by ID None To-do item
POST /api/todo Add a new item To-do item To-do item
PUT /api/todo/{id} Update an existing item To-do item None
DELETE /api/todo/{id} Delete an item. None None
The following diagram show the basic design of the app.
../_images/architecture.png
  • The client is whatever consumes the web API (browser, mobile app, and so forth). We aren’t writing a client in this tutorial.
  • A model is an object that represents the data in your application. In this case, the only model is a to-do item. Models are represented as simple C# classes (POCOs).
  • A controller is an object that handles HTTP requests and creates the HTTP response. This app will have a single controller.
  • To keep the tutorial simple the app doesn’t use a database. Instead, it just keeps to-do items in memory. But we’ll still include a (trivial) data access layer, to illustrate the separation between the web API and the data layer. For a tutorial that uses a database, see Building your first ASP.NET Core MVC app with Visual Studio.

Install Fiddler

We’re not building a client, we’ll use Fiddler to test the API. Fiddler is a web debugging tool that lets you compose HTTP requests and view the raw HTTP responses.

Create the project

Start Visual Studio. From the File menu, select New > Project.
Select the ASP.NET Core Web Application project template. Name the project TodoApi and tap OK.
../_images/new-project3.png In the New ASP.NET Core Web Application (.NET Core) - TodoApi dialog, select the Web API template. Tap OK.
../_images/web-api-project.png

Add a model class

A model is an object that represents the data in your application. In this case, the only model is a to-do item.
Add a folder named “Models”. In Solution Explorer, right-click the project. Select Add > New Folder. Name the folder Models.
../_images/add-folder.png
Note
You can put model classes anywhere in your project, but the Models folder is used by convention.
Next, add a TodoItem class. Right-click the Models folder and select Add > New Item.
In the Add New Item dialog, select the Class template. Name the class TodoItem and click OK.
../_images/add-class.png Replace the generated code with:
namespace TodoApi.Models
{
    public class TodoItem
    {
        public string Key { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

Add a repository class

A repository is an object that encapsulates the data layer, and contains logic for retrieving data and mapping it to an entity model. Even though the example app doesn’t use a database, it’s useful to see how you can inject a repository into your controllers. Create the repository code in the Models folder.
Start by defining a repository interface named ITodoRepository. Use the class template (Add New Item > Class).
using System.Collections.Generic;

namespace TodoApi.Models
{
    public interface ITodoRepository
    {
        void Add(TodoItem item);
        IEnumerable<TodoItem> GetAll();
        TodoItem Find(string key);
        TodoItem Remove(string key);
        void Update(TodoItem item);
    }
}
This interface defines basic CRUD operations.
Next, add a TodoRepository class that implements ITodoRepository:
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;

namespace TodoApi.Models
{
    public class TodoRepository : ITodoRepository
    {
        static ConcurrentDictionary<string, TodoItem> _todos = 
              new ConcurrentDictionary<string, TodoItem>();

        public TodoRepository()
        {
            Add(new TodoItem { Name = "Item1" });
        }

        public IEnumerable<TodoItem> GetAll()
        {
            return _todos.Values;
        }

        public void Add(TodoItem item)
        {
            item.Key = Guid.NewGuid().ToString();
            _todos[item.Key] = item;
        }

        public TodoItem Find(string key)
        {
            TodoItem item;
            _todos.TryGetValue(key, out item);
            return item;
        }

        public TodoItem Remove(string key)
        {
            TodoItem item;
            _todos.TryGetValue(key, out item);
            _todos.TryRemove(key, out item);
            return item;
        }

        public void Update(TodoItem item)
        {
            _todos[item.Key] = item;
        }
    }
}
Build the app to verify you don’t have any compiler errors.

Register the repository

By defining a repository interface, we can decouple the repository class from the MVC controller that uses it. Instead of instantiating a TodoRepository inside the controller we will inject an ITodoRepository the built-in support in ASP.NET Core for dependency injection.
This approach makes it easier to unit test your controllers. Unit tests should inject a mock or stub version of ITodoRepository. That way, the test narrowly targets the controller logic and not the data access layer.
In order to inject the repository into the controller, we need to register it with the DI container. Open the Startup.cs file. Add the following using directive:
using TodoApi.Models;
In the ConfigureServices method, add the highlighted code:
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    // Add our repository type
    services.AddSingleton<ITodoRepository, TodoRepository>();
}

Add a controller

In Solution Explorer, right-click the Controllers folder. Select Add > New Item. In the Add New Item dialog, select the Web API Controller Class template. Name the class TodoController.
Replace the generated code with the following:
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using TodoApi.Models;

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : Controller
    {
        public TodoController(ITodoRepository todoItems)
        {
            TodoItems = todoItems;
        }
        public ITodoRepository TodoItems { get; set; }
    }
}
This defines an empty controller class. In the next sections, we’ll add methods to implement the API.

Getting to-do items

To get to-do items, add the following methods to the TodoController class.
public IEnumerable<TodoItem> GetAll()
{
    return TodoItems.GetAll();
}

[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
    var item = TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return new ObjectResult(item);
}
These methods implement the two GET methods:
  • GET /api/todo
  • GET /api/todo/{id}
Here is an example HTTP response for the GetAll method:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/10.0
Date: Thu, 18 Jun 2015 20:51:10 GMT
Content-Length: 82

[{"Key":"4f67d7c5-a2a9-4aae-b030-16003dd829ae","Name":"Item1","IsComplete":false}]
Later in the tutorial I’ll show how you can view the HTTP response using the Fiddler tool.

Routing and URL paths

The [HttpGet] attribute specifies that these are HTTP GET methods. The URL path for each method is constructed as follows:
  • Take the template string in the controller’s route attribute, [Route("api/[controller]")]
  • Replace “[Controller]” with the name of the controller, which is the controller class name minus the “Controller” suffix. For this sample the name of the controller is “todo” (case insensitive). For this sample, the controller class name is TodoController and the root name is “todo”. ASP.NET MVC Core is not case sensitive.
  • If the [HttpGet] attribute also has a template string, append that to the path. This sample doesn’t use a template string.
For the GetById method, “{id}” is a placeholder variable. In the actual HTTP request, the client will use the ID of the todo item. At runtime, when MVC invokes GetById, it assigns the value of “{id}” in the URL the method’s id parameter.

Change the launch URL to “api/todo”

  • Right click on the project > Properties
  • Select the Debug tab and change the Launch URL to “api/todo”
../_images/launch.png To learn more about request routing see 🔧 Routing to Controller Actions.

Return values

The GetAll method returns a CLR object. MVC automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this method is 200, assuming there are no unhandled exceptions. (Unhandled exceptions are translated into 5xx errors.)
In contrast, the GetById method returns the more general IActionResult type, which represents a generic result type. That’s because GetById has two different return types:
  • If no item matches the requested ID, the method returns a 404 error. This is done by returning NotFound.
  • Otherwise, the method returns 200 with a JSON response body. This is done by returning an ObjectResult.

Use Fiddler to call the API

This step is optional, but it’s useful to see the raw HTTP responses from the web API. In Visual Studio, press ^F5 to launch the app. Visual Studio launches a browser and navigates to http://localhost:port/api/todo, where port is a randomly chosen port number. If you’re using Chrome, Edge or Firefox, the todo data will be displayed. If you’re using IE, IE will prompt to you open or save the todo.json file.
Launch Fiddler. From the File menu, uncheck the Capture Traffic option. This turns off capturing HTTP traffic.
../_images/fiddler1.png Select the Composer page. In the Parsed tab, type http://localhost:port/api/todo, where port is the port number. Click Execute to send the request.
../_images/fiddler2.png The result appears in the sessions list. The response code should be 200. Use the Inspectors tab to view the content of the response, including the response body.
../_images/fiddler3.png

Implement the other CRUD operations

The last step is to add Create, Update, and Delete methods to the controller. These methods are variations on a theme, so I’ll just show the code and highlight the main differences.

Create

[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
    if (item == null)
    {
        return BadRequest();
    }
    TodoItems.Add(item);
    return CreatedAtRoute("GetTodo", new { controller = "Todo", id = item.Key }, item);
}
This is an HTTP POST method, indicated by the [HttpPost] attribute. The [FromBody] attribute tells MVC to get the value of the to-do item from the body of the HTTP request.
The CreatedAtRoute method returns a 201 response, which is the standard response for an HTTP POST method that creates a new resource on the server. CreateAtRoute also adds a Location header to the response. The Location header specifies the URI of the newly created to-do item. See 10.2.2 201 Created.
We can use Fiddler to send a Create request:
  1. In the Composer page, select POST from the drop-down.
  2. In the request headers text box, add Content-Type: application/json, which is a Content-Type header with the value application/json. Fiddler automatically adds the Content-Length header.
  3. In the request body text box, enter the following: {"Name":"<your to-do item>"}
  4. Click Execute.
../_images/fiddler4.png Here is an example HTTP session. Use the Raw tab to see the session data in this format.
Request:
POST http://localhost:29359/api/todo HTTP/1.1
User-Agent: Fiddler
Host: localhost:29359
Content-Type: application/json
Content-Length: 33

{"Name":"Alphabetize paperclips"}
Response:
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: http://localhost:29359/api/Todo/8fa2154d-f862-41f8-a5e5-a9a3faba0233
Server: Microsoft-IIS/10.0
Date: Thu, 18 Jun 2015 20:51:55 GMT
Content-Length: 97

{"Key":"8fa2154d-f862-41f8-a5e5-a9a3faba0233","Name":"Alphabetize paperclips","IsComplete":false}

Update

[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody] TodoItem item)
{
    if (item == null || item.Key != id)
    {
        return BadRequest();
    }

    var todo = TodoItems.Find(id);
    if (todo == null)
    {
        return NotFound();
    }

    TodoItems.Update(item);
    return new NoContentResult();
}
Update is similar to Create, but uses HTTP PUT. The response is 204 (No Content). According to the HTTP spec, a PUT request requires the client to send the entire updated entity, not just the deltas. To support partial updates, use HTTP PATCH.
../_images/put.png

Delete

[HttpDelete("{id}")]
public void Delete(string id)
{
    TodoItems.Remove(id);
}
The void return type returns a 204 (No Content) response. That means the client receives a 204 even if the item has already been deleted, or never existed. There are two ways to think about a request to delete a non-existent resource:
  • “Delete” means “delete an existing item”, and the item doesn’t exist, so return 404.
  • “Delete” means “ensure the item is not in the collection.” The item is already not in the collection, so return a 204.
Either approach is reasonable. If you return 404, the client will need to handle that case.
../_images/delete.png

ASP.NET Web API 2


HTTP is not just for serving up web pages. It is also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop applications.
ASP.NET Web API is a framework for building web APIs on top of the .NET Framework. In this tutorial, you will use ASP.NET Web API to create a web API that returns a list of products.

Software versions used in the tutorial

Create a Web API Project

In this tutorial, you will use ASP.NET Web API to create a web API that returns a list of products. The front-end web page uses jQuery to display the results.

Start Visual Studio and select New Project from the Start page. Or, from the File menu, select New and then Project.
In the Templates pane, select Installed Templates and expand the Visual C# node. Under Visual C#, select Web. In the list of project templates, select ASP.NET Web Application. Name the project "ProductsApp" and click OK.

In the New ASP.NET Project dialog, select the Empty template. Under "Add folders and core references for", check Web API. Click OK.

You can also create a Web API project using the "Web API" template. The Web API template uses ASP.NET MVC to provide API help pages. I'm using the Empty template for this tutorial because I want to show Web API without MVC. In general, you don't need to know ASP.NET MVC to use Web API.

Adding a Model

A model is an object that represents the data in your application. ASP.NET Web API can automatically serialize your model to JSON, XML, or some other format, and then write the serialized data into the body of the HTTP response message. As long as a client can read the serialization format, it can deserialize the object. Most clients can parse either XML or JSON. Moreover, the client can indicate which format it wants by setting the Accept header in the HTTP request message.
Let's start by creating a simple model that represents a product.
If Solution Explorer is not already visible, click the View menu and select Solution Explorer. In Solution Explorer, right-click the Models folder. From the context menu, select Add then select Class.

Name the class "Product". Add the following properties to the Product class.
namespace ProductsApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

Adding a Controller

In Web API, a controller is an object that handles HTTP requests. We'll add a controller that can return either a list of products or a single product specified by ID.
Note  If you have used ASP.NET MVC, you are already familiar with controllers. Web API controllers are similar to MVC controllers, but inherit the ApiController class instead of the Controller class.
In Solution Explorer, right-click the Controllers folder. Select Add and then select Controller.

In the Add Scaffold dialog, select Web API Controller - Empty. Click Add.

In the Add Controller dialog, name the controller "ProductsController". Click Add.

The scaffolding creates a file named ProductsController.cs in the Controllers folder.

You don't need to put your contollers into a folder named Controllers. The folder name is just a convenient way to organize your source files. 
If this file is not open already, double-click the file to open it. Replace the code in this file with the following:
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace ProductsApp.Controllers
{
    public class ProductsController : ApiController
    {
        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public IHttpActionResult GetProduct(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
    }
}
To keep the example simple, products are stored in a fixed array inside the controller class. Of course, in a real application, you would query a database or use some other external data source.
The controller defines two methods that return products:
  • The GetAllProducts method returns the entire list of products as an IEnumerable<Product> type.
  • The  GetProduct method looks up a single product by its ID.
That's it! You have a working web API.  Each method on the controller corresponds to one or more URIs:
Controller MethodURI
GetAllProducts/api/products
GetProduct/api/products/id
For the GetProduct method, the id in the URI is a placeholder. For example, to get the product with ID of 5, the URI is api/products/5.
For more information about how Web API routes HTTP requests to controller methods, see Routing in ASP.NET Web API.

Calling the Web API with Javascript and jQuery

In this section, we'll add an HTML page that uses AJAX to call the web API. We'll use jQuery to make the AJAX calls and also to update the page with the results.
In Solution Explorer, right-click the project and select Add, then select New Item.

In the Add New Item dialog, select the Web node under Visual C#, and then select the HTML Page item. Name the page "index.html".

Replace everything in this file with the following:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Product App</title>
</head>
<body>

  <div>
    <h2>All Products</h2>
    <ul id="products" />
  </div>
  <div>
    <h2>Search by ID</h2>
    <input type="text" id="prodId" size="5" />
    <input type="button" value="Search" onclick="find();" />
    <p id="product" />
  </div>

  <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
  <script>
    var uri = 'api/products';

    $(document).ready(function () {
      // Send an AJAX request
      $.getJSON(uri)
          .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
              // Add a list item for the product.
              $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
          });
    });

    function formatItem(item) {
      return item.Name + ': $' + item.Price;
    }

    function find() {
      var id = $('#prodId').val();
      $.getJSON(uri + '/' + id)
          .done(function (data) {
            $('#product').text(formatItem(data));
          })
          .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
          });
    }
  </script>
</body>
</html>
There are several ways to get jQuery. In this example, I used the Microsoft Ajax CDN. You can also download it from http://jquery.com/, and the ASP.NET "Web API" project template includes jQuery as well.

Getting a List of Products

To get a list of products, send an HTTP GET request to "/api/products".
The jQuery getJSON function sends an AJAX request. For response contains array of JSON objects. The done function specifies a callback that is called if the request succeeds. In the callback, we update the DOM with the product information.
$(document).ready(function () {
    // Send an AJAX request
    $.getJSON(apiUrl)
        .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
                // Add a list item for the product.
                $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
        });
});

Getting a Product By ID

To get a product by ID, send an HTTP GET  request to "/api/products/id", where id is the product ID.
function find() {
    var id = $('#prodId').val();
    $.getJSON(apiUrl + '/' + id)
        .done(function (data) {
            $('#product').text(formatItem(data));
        })
        .fail(function (jqXHR, textStatus, err) {
            $('#product').text('Error: ' + err);
        });
}
We still call getJSON to send the AJAX request, but this time we put the ID in the request URI. The response from this request is a JSON representation of a single product.

Running the Application

Press F5 to start debugging the application. The web page should look like the following:

To get a product by ID, enter the ID and click Search:

If you enter an invalid ID, the server returns an HTTP error:

Using F12 to View the HTTP Request and Response

When you are working with an HTTP service, it can be very useful to see the HTTP request and request messages. You can do this by using the F12 developer tools in Internet Explorer 9. From Internet Explorer 9, press F12 to open the tools. Click the Network tab and press Start Capturing. Now go back to the web page and press F5 to reload the web page. Internet Explorer will capture the HTTP traffic between the browser and the web server. The summary view shows all the network traffic for a page:

Locate the entry for the relative URI “api/products/”. Select this entry and click Go to detailed view. In the detail view, there are tabs to view the request and response headers and bodies. For example, if you click the Request headers tab, you can see that the client requested "application/json" in the Accept header.

If you click the Response body tab, you can see how the product list was serialized to JSON. Other browsers have similar functionality. Another useful tool is Fiddler, a web debugging proxy. You can use Fiddler to view your HTTP traffic, and also to compose HTTP requests, which gives you full control over the HTTP headers in the request.

.NET Framework???

A programming infrastructure created by Microsoft for building, deploying, and running applications and services that use .NET technologies, such as desktop applications and Web services.
The .NET Framework contains three major parts:

Monday, May 26, 2014

Description about MVC, MVVM, MVP Patterns

MVC Pattern

MVC stands for Model-View-Controller. It is a software design pattern which was introduced in 1970s. Also, MVC pattern forces a separation of concerns, it means domain model and controller logic are decoupled from user interface (view). As a result maintenance and testing of the application become simpler and easier.
MVC design pattern splits an application into three main aspects: Model, View and Controller
  1. Model

    The Model represents a set of classes that describe the business logic i.e. business model as well as data access operations i.e. data model. It also defines business rules for data means how the data can be changed and manipulated.
  2. View

    The View represents the UI components like CSS, jQuery, html etc. It is only responsible for displaying the data that is received from the controller as the result. This also transforms the model(s) into UI.
  3. Controller

    The Controller is responsible to process incoming requests. It receives input from users via the View, then process the user's data with the help of Model and passing the results back to the View. Typically, it acts as the coordinator between the View and the Model.
Today, this pattern is used by many popular framework like as Ruby on Rails, Spring Framework, Apple iOS Development and ASP.NET MVC.

MVP pattern

This pattern is similar to MVC pattern in which controller has been replaced by the presenter. This design pattern splits an application into three main aspects: Model, View and Presenter.
  1. Model

    The Model represents a set of classes that describes the business logic and data. It also defines business rules for data means how the data can be changed and manipulated.
  2. View

    The View represents the UI components like CSS, jQuery, html etc. It is only responsible for displaying the data that is received from the presenter as the result. This also transforms the model(s) into UI.
  3. Presenter

    The Presenter is responsible for handling all UI events on behalf of the view. This receive input from users via the View, then process the user's data with the help of Model and passing the results back to the View. Unlike view and controller, view and presenter are completely decoupled from each other’s and communicate to each other’s by an interface.
    Also, presenter does not manage the incoming request traffic as controller.
This pattern is commonly used with ASP.NET Web Forms applications which require to create automated unit tests for their code-behind pages. This is also used with windows forms.

Key Points about MVP Pattern:

  1. User interacts with the View.
  2. There is one-to-one relationship between View and Presenter means one View is mapped to only one Presenter.
  3. View has a reference to Presenter but View has not reference to Model.
  4. Provides two way communication between View and Presenter.

MVVM pattern

MVVM stands for Model-View-View Model. This pattern supports two-way data binding between view and View model. This enables automatic propagation of changes, within the state of view model to the View. Typically, the view model uses the observer pattern to notify changes in the view model to model.
  1. Model

    The Model represents a set of classes that describes the business logic and data. It also defines business rules for data means how the data can be changed and manipulated.
  2. View

    The View represents the UI components like CSS, jQuery, html etc. It is only responsible for displaying the data that is received from the controller as the result. This also transforms the model(s) into UI..
  3. View Model

    The View Model is responsible for exposing methods, commands, and other properties that helps to maintain the state of the view, manipulate the model as the result of actions on the view, and trigger events in the view itself.
This pattern is commonly used by the WPF, Silverlight, Caliburn, nRoute etc.

Key Points about MVVM Pattern:

  1. User interacts with the View.
  2. There is many-to-one relationship between View and ViewModel means many View can be mapped to one ViewModel.
  3. View has a reference to ViewModel but View Model has no information about the View.
  4. Supports two-way data binding between View and ViewModel.
What do you think?
I hope you have understand the MVC, MVP and MVVM design patterns. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome.

MVC and MVVM

  • MVC = model, controller, view = essentially one-way communication = poor interactivity
  • MVVM = model, controller, cache, view = two-way communication = rich interactivity

Model-View-ViewModel design pattern

You can see an explanation of the MVVM Pattern in the Windows environment:
In the Model-View-ViewModel design pattern, an app is composed of three general components. enter image description here
  • Model: This represents the data model that your app consumes. For example, in a picture sharing app, this layer might represent the set of pictures available on a device and the API used to read and write to the picture library.
  • View: An app typically is composed of multiple pages of UI. Each page shown to the user is a view in MVVM terminology. The view is the XAML code used to define and style what the user sees. The data from the model is displayed to the user, and it’s the job of the ViewModel to feed the UI this data based on the current state of the app. For example, in a picture sharing app, the views would be the UI that show the user the list of albums on the device, the pictures in an album, and perhaps another that shows the user a particular picture.
  • ViewModel: The ViewModel ties the data model, or simply the model, to the UI, or views, of the app. It contains the logic with which to manage the data from the model and exposes the data as a set of properties to which the XAML UI, or views, can bind. For example, in a picture sharing app, the ViewModel would expose a list of albums, and for each album expose a list of pictures. The UI is agnostic of where the pictures come from and how they are retrieved. It simply knows of a set of pictures as exposed by the ViewModel and shows them to the user.

MVVM -VS -MVP -VS - MVC - THE-DIFFERENCES-EXPLAINED

Those who know me know that I have a passion for software architecture and after developing projects using Model-View-ViewModel (MVVM), Model-View-Presenter (MVP), and Model-View-Controller (MVC),  I finally feel qualified to talk about the differences between these architectures.  The goal of this article is to clearly explain the differences between these 3 architectures.

Common Elements

First, the let’s define common elements.  All 3 of the architectures are designed to separate the view from the model.

Model

  • Domain entities & functionality
  • Knows only about itself and not about views, controllers, etc.
  • For some projects, it is simply a database and a simple DAO
  • For some projects, it could be a database/file system, a set of entities, and a number of classes/libraries that provide additional logic to the entities (such as performing calculations, managing state, etc)
Implementation: Create classes that describe your domain and handle functionality.  You probably should end up with a set of  domain objects and a set of classes that manipulate those objects.

View

  • Code that handles the display
  • Note that view related code in the codebehind is allowed (see final notes at the bottom for details)
Implementation:  HTML, WPF, WindowsForms, views created programmatically – basically code that deals with display only.

Differences between Presenters, ViewModels and Controllers

This is the tricky part.  Some things that Controllers, Presenters, and ViewModels have in common are:
  • Thin layers
  • They communicate with the model and the view
The features of each.

Presenter (Example: WinForms)

  • 2 way communication with the view
  • View Communication: The view communicates with the presenter by directly calling functions on an instance of the presenter.  The presenter communicates with the view by talking to an interface implemented by the view.
  • There is a single presenter for each view
Implementation:
  • Every view’s codebehind implements some sort of IView interface.  This interface has functions like displayErrorMessage(message:String), showCustomers(customers:IList<Customer>), etc.  When a function like showCustomers is called in the view, the appropriate items passed are added to the display.  The presenter corresponding to the view has a reference to this interface which is passed via the constructor.
  • In the view’s codebehind, an instance of the presenter is referenced.  It may be instantiated in the code behind or somewhere else.  Events are forwarded to the presenter  through the codebehind.  The view never passes view related code (such as controls, control event objects, etc) to the presenter.
A code example is shown below.
//the view interface that the presenter interacts with
public interface IUserView
{
    void ShowUser(User user);
    ...
}
 
//the view code behind
public partial class UserForm : Form, IUserView
{
    UserPresenter _presenter;
    public UserForm()
    {
        _presenter = new UserPresenter(this);
        InitializeComponent();
    }
 
    private void SaveUser_Click(object sender, EventArgs e)
    {
        //get user from form elements
        User user = ...;
        _presenter.SaveUser(user);
    }
 
    ...
}
 
public class UserPresenter
{
    IUserView _view;
    public UserPresenter(IUserView view){
        _view = view;
    }
 
    public void SaveUser(User user)
    {
 ...
    }
    ...
}

ViewModel (Example: WPF, Knockoutjs)

  • 2 way communication with the view
  • The ViewModel represents the view.  This means that fields in a view model usually match up more closely with the view than with the model.
  • View Communication:  There is no IView reference in the ViewModel.  Instead, the view binds directly to the ViewModel.  Because of the binding, changes in the view are automatically reflected in the ViewModel and changes in the ViewModel are automatically reflected in the view.
  • There is a single ViewModel for each view
Implementation:
  • The view’s datacontext is set to the ViewModel.  The controls in the view are bound to various members of the ViewModel.
  • Exposed ViewModel proproperties implement some sort of observable interface that can be used to automatically update the view (With WPF this is INotifyPropertyChanged; with knockoutjs this is done with the functions ko.observable() and ko.observrableCollection())

Controller (Example: ASP.NET MVC Website)

  • The controller determines which view is displayed
  • Events in the view trigger actions that the controller can use to modify the model or choose the next view.
  • There could be multiple views for each controller
  • View Communication:
    • The controller has a method that determines which view gets displayed
    • The view sends input events to the controller via a callback or registered handler.  In the case of a website, the view sends events to the controller via a url that gets routed to the appropriate controller and controller method.
    • The view receives updates directly from the model without having to go through the controller.
      • Note: In practice, I don’t think this particular feature of MVC is employed as often today as it was in the past.  Today, I think developers are opting for MVVM (or MVP) over MVC in most situations where this feature of MVC would have been used.  Websites are a situation where I think MVC is still a very practical solution.  However, the view is always disconnected from the server model and can only receive updates with a request that gets routed through the controller.  The view is not able to receive updates directly from the model.
Implementation (for web):
  • A class is required to interpret incoming requests and direct them to the appropriate controller.  This can be done by just parsing the url.  Asp.net MVC does it for you.
  • If required, the controller updates the model based on the request.
  • If required, the controller chooses the next view based on the request.  This means the controller needs to have access to some class that can be used to display the appropriate view.  Asp.net MVC provides a function to do this that is available in all controllers.  You just need to pass the appropriate view name and data model.
MVVM and MVP implementation seem pretty straightforward but MVC can be a little confusing.  The diagram below from Microsoft’s Smart Client Factory documentation does a great job at showing MVC communication.  Note that the controller chooses the view (ASP.NET MVC) which is not shown in this diagram.  MVVM interactions will look identical to MVP (replace Presenter with ViewModel).  The difference is that with MVP, those interactions are handled programmatically while with MVVM, they will be handled automatically by the data bindings.

General rules for when to use which?

MVP
  • Use in situations where binding via a datacontext is not possible.
  • Windows Forms is a perfect example of this.  In order to separate the view from the model, a presenter is needed.  Since the view cannot directly bind to the presenter, information must be passed to it view an interface (IView).
MVVM
  • Use in situations where binding via a datacontext is possible.  Why?  The various IView interfaces for each view are removed which means less code to maintain.
  • Some examples where MVVM is possible include WPF and javascript projects using Knockout.
MVC
  • Use in situations where the connection between the view and the rest of the program is not always available (and you can’t effectively employ MVVM or MVP).
  • This clearly describes the situation where a web API is separated from the data sent to the client browsers.  Microsoft’s ASP.NET MVC is a great tool for managing such situations and provides a very clear MVC framework.

Final notes

  • Don’t get stuck on semantics.  Many times, one of your systems will not be purely MVP or MVVM or MVC.  Don’t worry about it.  Your goal is not to make an MVP, MVVM, or MVC system.  Your goal is to separate the view, the model, and the logic that governs both of them. It doesn’t matter if your view binds to your ‘Presenter’, or if you have a pure Presenter mixed in with a bunch of ViewModels.  The goal of a maintainable project is still achieved.
  • Some evangelists will say that your ViewModels (and Presenters) must not make your model entities directly available for binding to the view.   There are definitely situations where this is a bad thing.  However, don’t avoid this for the sake of avoiding it.  Otherwise, you will have to constantly be copying data between your model and ViewModel.  Usually this is a pointless waste of time that results in much more code to maintain.
  • In line with the last point, if using WPF it makes sense to implement INotifyPropertyChanged in your model entities.  Yes, this does break POCO but when considering that INotifyPropertyChanged adds a lot of functionality with very little maintenance overhead , it is an easy decision to make.
  • Don’t worry about “bending the rules” a bit so long as the main goal of a maintainable program is achieved
  • Views
    • When there is markup available for creating views (Xaml, HTML, etc), some evangelists may try to convince developers that views must be written entirely in markup with no code behind.  However, there are perfectly acceptable reasons to use the code behind in a view if it is dealing with view related logic.  In fact, it is the ideal way to keep view code out of your controllers, view models, and  presenters.  Examples of situations where you might use the code behind include:
      • Formatting a display field
      • Showing only certain details depending on state
      • Managing view animations
    • Examples of code that should not be in the view
      • Sending an entity to the database to be saved
      • Business logic