Saturday, February 9, 2013

Controller


ASP.Net MVC Controller is the fifth post in a series of tutorials which introduces the basics of ASP.Net MVC programming.

You can download the example code for the Model, View and Controller posts here. Visual Studio 2012 is required. If you don't have a copy, you can download a free copy of Visual Studio 2012 for Web.

Previous Posts:
MVC Introduction
HTML Forms
Model
View

Controllers

Controllers are responsible for responding to requests made on an ASP.Net MVC website. On a non-MVC site, a request is made explicitly for a file e.g. http://www.blogger.com/index.html. In MVC the request is made to the controller. Requests are either GET or POST which I reviewed in the second post on MVC.
This can be a difficult concept at first as there is a tendency to think that the View e.g. Edit.cshtml file is what is being requested but in actual fact the Controller is the first port of call and you can decide what view you want to display in the Controller.

Like Models and Views, there is a convention for how Controllers are named and where they are stored. Controllers are stored in the Controllers folder and are generally named to match the object with 'Controller' appended to the end e.g. PeopleController. Notice I am using People and not Person. Plural names are used for Controllers e.g. Cars, Products, People, etc.

If you look in the Controllers folders, there should be two controllers there which are generated from a template. AccountController manages registration and logins and the HomeController is a generic controller that manages the Views in the Home folder which current is the Index and About view.


We will add a Controller for our Person.

To add a Controller, right click on the Controllers folder, select add and then Controller. Name the controller PeopleController.
Select Controller with empty read/write actions as the template.


Like Add View, ASP.Net MVC will scaffold basic code to get started with a Controller.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Acme.Intranet.Models;

namespace Acme.Intranet.Controllers
{
    public class PeopleController : Controller
    {
        //
        // GET: /People/

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

        //
        // GET: /People/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /People/Create

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

        //
        // POST: /People/Create

        [HttpPost]
        public ActionResult Create(Person person)
        {
            try
            {
                // TODO: Add insert logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
        
        //
        // GET: /People/Edit/5

        public ActionResult Edit(int id)
        {
            return View();
        }

        //
        // POST: /People/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, Person person)
        {
            try
            {
                // TODO: Add update logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /People/Delete/5

        public ActionResult Delete(int id)
        {
            return View();
        }

        //
        // POST: /People/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, Person person)
        {
            try
            {
                // TODO: Add delete logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
}


The Controller will contain a number of actions which return ActionResults which are a generic class that are returned by controllers. There are more complex return types but they are generally inherited from ActionResult.

The View created in the previous post provides a form for a person to be created. I will concentrate on the Actions for Create only. Notice there are two Create functions. The first is a GET action and he second is a POST action. You can restrict the action to POST by placing [HttpPost] attribute above the action.

As noted in the previous post on HTML forms, GET is primarily used to retrieve data while POST is used to submit data. MVC is a commonly referred to as a RESTful architecture. The client requests resources from the server e.g. a web page, the server then rests and does nothing until another GET or POST action is requested. In between requests, the server goes off and serves other requests. This is extremely efficient and is the significant reason for the success of the internet. Windows applications based on a client server model would run out of memory very quickly if it had to deal with the amount of requests that some web sites have to deal with. This is because windows applications retain a relationship with the client requesting information and must allocate memory for each client.

First, lets look at the GET action. The function will return a View when http://acme/people/create is requested. Hows does MVC know where to find the Create function. Again MVC relies on convention. MVC has a routing mechanism which will be expanded upon in a separate post. If you don't change anything, the following routing applies:

domain/controller/action e.g. http://acme/people/create, http://localhost:1388/car/delete

So MVC looks carefully at the URL and knows that everything after http:// and before the first / is the domain, the next part s the Controller and the last part is the Action. Note, the Controller part is omitted from the URL so PeopleController becomes people. The URL is not case sensitive so people is the same as People.


        //
        // GET: /People/Create

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


The GET action returns a View. For now, think of a view as an empty model e.g. Person. If you want to populate the initial web form with some data, you can initialise a new person object and return it. If we had included a DateCreated field in person:


        //
        // GET: /People/Create

        public ActionResult Create()
        {

            Person person = new Person();
            person.DateCreated = DateTime.Now;

            Viewbag.Title="New Person";

            return View(person);
        } 


         

Now every person is initialised with the DateCreated set to the current date and time.

That is all that is required to show the person on the View. We now need a function to accept the POST action. The following function does nothing really but return the user to a view named Index. Note, the scaffolding that created the controller may have included a FormsCollection object instead of the Person object. Replace public ActionResult Create(FormCollection collection) with public ActionResult Create(Person person) as below:


        //
        // POST: /People/Create

        [HttpPost]
        public ActionResult Create(Person person)
        {
            try
            {
                // TODO: Add insert logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

Also ensure that the namespace which Person belongs to is referenced at the top e.g. using Acme.Intranet.Models;

The POST action returns a RedirectToAction which causes the browser to issue a GET request. In the example above, after the code is completed, the browser will go to the Index view for the Person e.g. http://acme/people/index. You an change this to return RedirectToAction("Edit"); and it will return to the current Edit view.

Important: If the [HttpPost] attribute is not placed above the action, the action method will be assumed to be GET.

Initially MVC may seem like a lot of overhead as there are a lot of new concepts to learn if you have come from ASP.Net forms or scripting languages. The good news is that MVC follows rules and once you become familiar with these rules, it makes life so much simpler.

You can download the example code for the Model, View and Controller posts here.

If you haven't used Visual Studio before, run the Visual Studio application, from the File menu select Oen Project, browse to the location where you extracted the files and select MvcTutorial1.sln. After the application loads, click the F5 button or select Start Debugging from the Debugging menu. The ASP.Net MVC application will open in your default browser. The initial URL will be a series of numbers like http://localhost:49529/. Type People/Create after the URL address e.g. http://localhost:49529/People/Create.
Hopefully you will see a web page similar to below:


Note: The form will not save data yet as we have not added a repository.

Concepts covered

  1. Controllers
  2. Actions
  3. Routing
  4. ActionResult
  5. GET versus POST actions
  6. Initialising objects for Views
  7. Return Views

The next post will review the Model, View, Controller paradigm based on the code so far before introducing a way to save our new Person to a repository or a database.

Friday, February 8, 2013

View


ASP.Net MVC View is the fourth post in a series of tutorials which introduces the basics of ASP.Net MVC programming.

Previous Posts:
MVC Introduction
HTML Forms
Model

Views


IN MVC, Views are what we see and interact with. The view can be a web page on a desktop, tablet or mobile device. The view can also be an app or a console application or any number of options for interacting with an application. ASP.Net MVC controllers supports the concept of returning views which are web pages, but controllers can also return JSON, XML and many other formats which can be consumed by numerous devices. In fact a request to a server can return the same data which can be shown differently depending on the device. The server is not very concerned about what device consumes the data, it just knows a request has been made and data must be processed and return in a particular format. This concept is termed 'separation of concerns' and is a powerful concept that differentiates ASP.Net forms from ASP.Net MVC.

Mobile and tablet devices are becoming more popular than desktop and notebooks and while this has been primarily consumer led until now, this progression is started to take hold in business. Developing separate applications for different devices is a luxury that is difficult to justify for most businesses. There are ways and means to optimise and reduce the server side code but the connection between the user interface and business logic is problematic. MVC has come at a good time for web and mobile based applications.

Razor

As per my Model tutorial, I will be programming in C#. I will also be using Razor as the syntax in the ASP.Net web page. Razor is almost identical to C# if you are using C# for your project and is the code that will be inter-dispersed with your HTML syntax. Razor is relatively new and was introduced with MVC 3. Prior to that a similar syntax was used to that in ASP.Net forms which used <%= %> to distinguish ASP.Net code from HTML. Razor uses an @ symbol which is far easier to read. If you are starting out, I would suggest using Razor otherwise use what ever you are comfortable with. Note - although ASP.Net code is inter-dispersed with HTML which cannot be avoided, I tend to use it cautiously and avoid or minimise placing business logic in the View.

The View

There will be a little more explanation when I get to Controllers but for now think of a view as a web page. In C#, the web page will have an extension of cshtml and in VB.Net it will be vbhtml. The web server will do the necessary processing to convert these files to HTML.

Strongly typed views

MVC3 introduced the concept of strongly typed views. Basically this means each web form is strongly associated with one object e.g. Person, Car, Project. One object = one form. You can have more than one form on a web page in MVC but this can be a little head wrecking in the beginning as there is a tendency to be loose with the data that is retrieved and stored to and from a server. For example if you are working with a SQL database, you can query data for a web page based on joins on many tables and now MVC is restricting you to only one object which is associated with one table in a SQL database. But don't worry, there are techniques to overcome this restriction. You can workaround the strongly typed view concept by using dynamic types but it doesn't make for great coding and you loose the IntelliSense in Visual Studio. I stick to strongly typed views where ever possible as it is a self organising process which produces better outputs.

Standard folders and files

Following the convention over configuration theme, MVC expects certain files and folders to be in the right place. This convention provides great familiarity across projects.

In the Solution Explorer, expand the Views folder. Note the View folder is a standard MVC folder. There will be a number of standard folders and views within the views folder which were generated based on a template.
The Account folder contains views used for logging on to your site. I will cover this in detail on a separate post.
The Shared folder is a standard MVC folder that contains views that are accessible universally. MVC does its best to find an explicitly defined view. If it cannot find it, it will look in the Shared folder. The shared folder is commonly used for templates and common views that occur throughout a web application e.g. advert, the latest news or an error page.
The Home folder is akin to the root folder of a conventional website. The Index file for the website resides here and optionally other files can also. The bulk on the view for a website can be located in the Home folder which is not uncommon for a small web site. Larger sites will contain more folders organised based on object names. ASP.Net MVC does a little bit of MVC magic to route requests from the root index file to the home index file e.g. http://acme/ gets mapped to http://acme/home/index.


In the root of the Views folder is a special partial view named _ViewStart.cshtml. This partial view is used for all views in the Views folder. If you open the file, you will notice one line of code which defines the layout as referencing "~/Views/Shared/_Layout.cshtml". This is basically saying that all views should use _Layout.cshtml in the ~/Views/Shared/ folder for the Layout. A layout is akin to a template.
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

Partial Views are prefixed with an underscore e.g. _Layout.cshtml. Partial Views are subsets of Views and are not used to display a web page but can be used to display part of a web page. In the case of the template, they are often used to display the header, menus, footer and so on that are common to all views.

  1. We are going to create a view to allow a person to be created. First create a folder named People under views. Note, the plural is used. Again this is convention.
  2. Then create a View named Create by right clicking on the Person folder, selecting Add and then selecting view.
  3. Select Razor (CSHTML) as the View Engine. Note, you can use a combination of Razor and ASPX (C#) but not in the same view. If you are new to MVC, then select Razor.
  4. Select Create a strongly-typed view. From the Model class pull down list, select Person (Acme.Intranet.Models). This is the class we created in the Model post.
  5. Select Edit from the list of Scaffold templates.
  6. Leave the text box for the layout or master page empty. We are going to use the layout defined in the _ViewStart.cshtml file.





If you used the settings in the form above, you should have the following code. Notice the @ symbol and the @ { } symbols. Razor uses the @ symbol to distinguish C# code from HTML code. @ { } is used to define a block or numerous lines of C# code.

@model Acme.Intranet.Models.Person

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Age)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Height)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Height)
            @Html.ValidationMessageFor(model => model.Height)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>


MVC used Scaffolding to automatically generate the above code. Scaffolding was popularised by Ruby on Rails and is very useful for generating common code that occurs in CRUD (Create, Read, Update, Delete) operations.

At the top, the strongly typed view is defined by the @model statement. @model Acme.Intranet.Models.Person basically says that this form is is strongly typed to the Person object.

ViewBag is like a super variable that was introduced in MVC 3. Prior to MVC 3 ViewData was used. If you are new to MVC, you can ignore ViewData for now as they are used for similar functions. ViewBag can contain just about anything you want it to. It can store an object, a collection of objects, a simple string or integer or an array. ViewBag goes against the principals of MVC so a little care needs to be taken when using it. I will expand of ViewBag in the Controllers post.

Notice that many of the Razor code lines start with @Html. MVC contains items called Html helpers which are a set of defined functions that automate the generation of HTML code. Unlike ASP.Net forms, in MVC the automation is at a more granular level and importantly can be overridden or extended.


@Html.BeginForm() - This will output standard HTML for a form.
@Html.LabelFor - This will create static text for a label.
@Html.EditorFor - MVC will output the best html form element i.e. Input type="text" for strings such as Firstname
@Html.ValidationSummary - Displays a message if the form field is incomplete or has an invalid input. I will cover this in detail in a separate post.

The form contains a standard HTML submit button.

Outside the form, at the bottom of the view is a simple Html.ActionLink helper. This will create a hyperlink to another view, one named Index in this case. Html.ActionLink will be covered in a separate post but for now you can create simple links to other views using Html.ActionLink providing two parameters, the first being the text to display in the hyperlink and the second being the View name. @Html.ActionLink("Edit Employee", "Edit")


Concepts covered

  1. Seperation of Concerns
  2. Razor
  3. Strongly Typed Views
  4. Standard MVC View folders
  5. Partial Views
  6. _ViewStart.cshtml file
  7. Scaffolding
  8. CRUD (Create, Read, Update and Delete)
  9. Html Helpers
  10. ViewBag
Although our view is quite simple, it is sufficient for us to present a View that will create a Person. We still need a Controller to complete the MVC pattern for it all to work. The next post will introduce Controllers.


Sunday, February 3, 2013

WCF versus ASP.Net API

This is a slight diversion from my ongoing ASP.Net MVC tutorial but there is relevance even if it may not seem like light reading.

I just sat down this morning to familiarise myself with Windows Communication Foundation or WCF for short. WCF is a framework for building service oriented applications and allows data to be sent asynchronously from one service to another. The client can be a web page, a mobile application or a desktop application such as Microsoft Excel. I was beginning to wonder why I hadn't delved into it previously as my final year project at Trinity College in 2001 was based on loosely coupled web services which I used to develop an Enterprise Resource Planning system. WCF hadn't yet come on the scene in 2001. Microsoft were busy developing Simple Object Access Protocol (SOAP) which is a specification for exchanging messages using XML.

Microsoft combined SOAP with Web Services Description Language (WSDL) to produce WCF which integrated web services into windows applications. It did solve many issues of previous messaging systems such as a single programming model which could be extended to support future transport protocols and messaging formats. I had considered SOAP in my final year project but at the time it was relatively new and there was significant overhead over XML over HTTP which at the time appeared to be a very lightweight and flexible alternative. Most of my applications were web based, so I developed my own little framework at the time using XMLHTTP, Javascript and Classic ASP which worked really well and was flexible enough to adapt to most problems that confronted me. AJAX came out a couple of years later as a formalisation of the XML over HTTP framework, made popular by Google. With the popularity of the web, the lightweight frameworks became popular especially for non critical applications.

When ASP.Net 2.0 came along, I started to look into it as the the missing link in my application was an Object Oriented approach to the business logic. Perhaps having come from a lightweight and flexible approach to web services, I found ASP.Net very heavy and disorganised. With ASP.Net, although I could now create classes for my objects which I felt was important to put some order on my business logic, I considered the tight binding of the User Interface and the business logic through the code behind method to very messy. ASP.Net seemed OK for very small applications but led to a lot of redundant code for larger applications. My lightweight application using XML over HTTP continued to do the business so it is unlikely that WCF would have interested me. With a little influence from Ruby on Rails, thankfully Microsoft redeemed themselves with ASP.Net MVC. And now with .Net 4, Microsoft have delivered Web.API which is very interesting.

After doing a little research into WCF, I started to wonder if there are more than a  few confused developers out there since Microsoft's decision to move Web API from WCF over to ASP.Net MVC. Have a look at Microsoft's 2006 article 'Future of ASP.Net Web Services in the context of Windows Communication Foundation' versus Microsoft's recent roadmap for Web API. Clearly Microsoft's focus has shifted towards web technologies and HTTP is now clearly the protocol of choice.

If HTTP is your preferred transport protocol, for the most part the same end result can be achieved using both Web API and WCF frameworks as WCF now supports HTTP and RESTful web services. Once you have invested in a technology such as WCF, you are less inclined to make any sudden moves to the latest technologies as the bleeding edge can be more than slightly uncomfortable. Microsoft realise this and will continue to support WCF but it is starting to become clear that there are two camps emerging, the ASP.Net/WCF and MVC/Web API.

My personal preference is MVC/Web API but I am slightly biased towards the MVC framework, also because I have not put considerable investment in ASP.Net but importantly because of the pure simplicity of MVC. MVC has simple convention rules which imposes structure on applications that has enormous benefit for projects especially for large teams. Being able to look at a project you are not familiar with and immediately knowing where the models are, that all data access is contained in neat data repository files for each model and the UI contains the minimum of business logic thus allowing the UI guys and girls to be creative without the overhead of intermingled code. Now extend this slightly and you get an asynchronous messaging system. This is where convention over configuration comes into its own. Web API supports numerous clients including Web, Mobile and desktop applications and is likely to extend further as the end service only needs a URL and the ability to consume popular formats such as XML, JSON and a range of other formats. Due to the general popularity of the OAuth framework for open standard authorisation and Microsofts integration of OAuth2 in MVC4, it appears to be gaining popularity for securing Web API messages. The concepts of OAuth should be familiar for anyone who has used payment systems such as PayPal. A full list of applications that support OAuth can be found on Wikipedia.

Summary
ASP.NET API is a framework for building non-SOAP based services over HTTP only whereas Windows Communication Foundation is designed to exchange SOAP-based messages using variety of transport protocols like HTTP, TCP, NamedPipes or MSMQ etc. If you need to support a variety of transport protocols, or the slower performance of HTTP is a consideration, WCF will continue to be the popular. ASP.Net API is certainly one to watch as the web gains popularity as the platform for business applications.