Tutorial: Creating a Web Project in F# Using an Online Template
Applies to: Functional Programming
Authors: Tomas Petricek and Jon Skeet
Get this book in Print, PDF, ePub and Kindle at manning.com. Use code “MSDN37b” to save 37%.
Summary: This tutorial demonstrates how to use Online Templates in Visual Studio to create a simple web application in F# using ASP.NET MVC 3.
This topic contains the following sections.
- Creating Web Projects in F#
- Using Online Templates
- Understanding the Template Structure
- Summary
- Additional Resources
- See Also
This article is associated with Real World Functional Programming: With Examples in F# and C# by Tomas Petricek with Jon Skeet from Manning Publications (ISBN 9781933988924, copyright Manning Publications 2009, all rights reserved). No part of these chapters may be reproduced, stored in a retrieval system, or transmitted in any form or by any means—electronic, electrostatic, mechanical, photocopying, recording, or otherwise—without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews.
Creating Web Projects in F#
When creating F# projects, it is possible to start with one of the preinstalled templates for creating basic types of projects. The templates include a basic console application, library, and Silverlight library. F# is not limited to these types of projects and can be used in a wide range of other scenarios including both server-side and client-side web applications. This tutorial shows how to create a Web application in F# using ASP.NET MVC 3.
When using the ASP.NET MVC Framework to develop web applications, the application consists of the following components:
Model. Implements an application's business logic, such as working with databases, calling services, and data processing.
Views. Creates a web application's user interface using HTML and CSS and specifies how to render the data returned from the model. It may also contain some JavaScript code that is run on the client.
Controller. Connects the front-end view with the back-end model. The controller validates inputs and calls the model to retrieve data depending on the parameters specified by the user (that are obtained from the view).
In ASP.NET MVC, model and controller are just standard .NET types that have specific names and expose methods required by the framework. The view can be written using one of several view engines. A view engine defines the format used for writing the user interface code. The code is usually a mix of HTML markup with embedded snippets in some language (such as C#, Visual Basic, or F#).
The samples presented in this chapter use F# to implement models as well as controllers. The view engine used throughout the examples is Razor, which is a light-weight language that combines HTML with embedded C# code. This is one of the standard options that are available in MVC 3. Some of the alternative options are discussed at the end of this article.
Using Online Templates
The F# templates in Microsoft® Visual Studio 2010 do not include a template for creating F# web applications. However, it is possible to select one of the numerous online templates contributed by the F# community. This article uses one such template. The template is fairly simple and it just creates a solution containing a front-end ASP.NET MVC project (that uses C# and Razor) and a back-end library project in F#.
The following steps show how to create an empty F# web application using the online template. The rest of the article explains the template and adds some interesting functionality.
To create a new project using online template, go to the New Project dialog.
In the dialog, select Online Templates from the tab on the left side.
Explore the templates by searching forF#, fsharp, or F# web application.
This article uses the F# Empty Web (MVC3 Razor) template. Figure 1 shows the template selected in the New Project dialog.
Specify the location for the solution and the solution name (AnagramWeb in this case) and click OK. This will generate solution with two projects named FSharpWeb.Core and FSharpWeb.Web that can be manually renamed.
The template used in this tutorial (as well as most of the other F# templates) is available under the permissive MS-PL license. If you agree with the license terms, click Accept to accept the license and create the project.
Figure 1. The New Project dialog showing online F# templates
The F# Empty Web template creates a solution containing two projects. One project is an F# library containing the back-end functionality and the second is a C# web application containing the user interface code. The rest of the article explains the project structure in more detail.
Understanding the Template Structure
The structure of the solution created by the template is shown in Figure 2. It contains the following two projects:
Project FSharpWeb.Core is an F# library that contains a model and controller implementation. The project contains references to all of the necessary ASP.NET MVC assemblies.
Project FSharpWeb.Web is a C# web project (using ASP.NET MVC3). It references the F# library to import its functionality. This project contains just the views that define the look of the website. The project uses the Razor view engine. The views have the .cshtml extension and are located in the Views directory.
The project contains two web pages. When started, it opens the Index page (also called action) that is handled by a controller called Main. The page creates a form that can be filled and submitted. After data is entered, the application navigates the user to a Hello page (also handled by Main controller).
Figure 2. The web project created using a template
The F# project contains a single file that contains the code of the controller (Main.fs) and a single file that contains the model with the functionality used by controllers (Model.fs). The next two sections discuss the model and the controller. The last file in the F# project (Global.fs) configures the application and is discussed later.
Exploring the F# Model
The model source code doesn't have any specific structure. A model is just a component that includes all of the important functionality such as data access code, the calling of web services, and the processing and validation of data. A model can span multiple F# source files. If it is more complicated, it can also be implemented in a separate project.
In the template (as well as in the rest of the examples created in the chapter), the model is just a single file. The sample model in the template contains a single F# function wrapped in a module named Model:
namespace FSharpWeb.Core
/// Data model implemented as an F# module with functions
module Model =
/// Say hello to the specified person
let sayHello name =
"Hello " + name + "!"
Web applications are typically stateless. This approach fits very well with functional programming, and it is often very natural to expose most of the functionality as functions in a module. When loading the data from a database, the data can be returned as records or objects, but the model can still expose a main module for calling this functionality.
The sayHello function from the Model.fs file is used in the Main controller. The next section looks at the controller source code.
Exploring the F# Controller
Controllers are responsible for responding to a request made against the ASP.NET MVC web page. An application can contain multiple controllers that group logically related actions (such as working with user accounts or editing and listing products). The sample template contains just a single controller named Main.
The request URL such as /Products/Category/3 is mapped to an action in a controller. The mapping is defined in the Global.fs file and will be explained later. The controller in the template supports two actions. The Index action doesn't have any inputs and it just displays a static page (defined by the view). The Hello controller takes a name as an argument and it passes some data to the view page:
namespace FSharpWeb.Core.Controllers
open System.Web.Mvc
open FSharpWeb.Core
/// Main controller for ASP.NET MVC pages
[<HandleError>]
type MainController() =
inherit Controller()
// Index action (accessed via /Main/Index)
member this.Index() =
this.View()
// Hello action takes user name as HTTP POST parameter
member this.Hello(user:string) =
this.ViewData.Model <- Model.sayHello user
this.View()
Following the usual programming style, controllers are placed in a separate Controllers namespace in the main namespace of the application. The snippet declares a single controller named Main. The framework requires implementing it as a class called MainController that inherits from the Controller class.
A controller contains a single method for each action that it can handle. The Index method doesn't implement any functionality so it just returns control to the MVC Framework and asks it to generate the view.
The Hello method is more interesting. It has a parameter named user (representing an entered name). The name of the parameter is not arbitrary - it matches the name that will be used later when generating an HTML form. The MVC Framework automatically provides the value of the parameter when calling the method. In response, the method calls the sayHello function from the model and returns the resulting string to the view. The value stored in the ViewData.Model property by a controller can be accessed from a view later.
The C# project contains one file specifying the views for each of the controller actions. The following section explains the Razor markup used in the views.
Exploring C# Razor Views
Application views can be found in the Views directory of the FSharpWeb.Web project. The Shared subdirectory contains a file named _Layout.cshtml, which defines the common parts of the application's web pages (such as headers, footers, and reference to CSS style sheets).
Views associated with the Main controller can be found in the Main subdirectory. The following listing shows the content of the Index.cshtml, which corresponds to the Index controller (and is used when the application loads for the first time):
@{ View.Title = "Home Page"; }
<h2>Welcome</h2>
Please enter your name:<br />
@using (Html.BeginForm("Hello", "Main"))
{
@Html.TextBox("user")
<input type="submit" value="Hello!" />
}
A .cshtml file consists mostly of the usual HTML markup. The sample above is very minimalistic, but it contains several standard HTML tags such as <h2> and <input>. When using a layout template, the generated code will be combined with the code specified in _Layout.cshtml (that contains all required HTML headers).
The parts marked with the @ symbol are embedded C# snippets. The first line sets the Title of the page, which is rendered by the template used by _Layout.cshtml. The next snippet defines a block using the C# using construct. The block specifies that the body should be wrapped in a HTML <form> element. The arguments to BeginForm specify the controller and the action that handles the form when it is submitted. In this example, the form will be handled by the Hello action (method) of the Main controller (MainController type in the F# project).
Next, the snippet renders an HTML <input> element where the user can enter his or her name. The argument of the TextBox method takes a name of the input. This name corresponds to the name of the parameter of the Hello method declared earlier in F#. When the form is submitted using the "Hello!" button, ASP.NET MVC automatically matches the name of HTML form elements with the names of parameters of the method and calls Hello to process the request.
The Hello method was shown earlier. It stores the result into the ViewData.Model property and then displays the following view:
@{ View.Title = "Hello page"; }
<h2>@Model</h2>
The view is extremely simple. It just sets the title of the page (just like the previous view) and then creates a <h2> heading containing the text provided by the controller. When the user enters "World" into the text box on the first page, the second page will show "Hello World".
Although simplistic, the example demonstrates the usual data and control flow of a web application created using ASP.NET MVC. A page can render a form that specifies the next action. The controller is called, it loads data using the model and transfers control to the view, which renders a page. The end of the article contains links to tutorials that demonstrate more realistic scenarios, but they all follow the same pattern.
The following section shows the last important part of the application, which configures the routing. Routing specifies how the URLs of the application look.
Exploring Routing Configuration
The ASP.NET routing module is responsible for mapping URL addresses of requests to appropriate controllers. The routing mechanism is quite general. For example, it can specify that a request to /product/42 be handled by a specific action with 42 passed as an argument to the method that implements the action.
The routing is configured when the application starts. At that point, it loads the main object that represents the application and is defined by the Global.asax file in the C# part of the solution:
<%@ Application Inherits="FSharpWeb.Core.Global" Language="C#" %>
<script Language="C#" runat="server">
protected void Application_Start(Object sender, EventArgs e) {
// Delegate event handling to the F# Application class
base.Start();
}
</script>
The file doesn't contain the actual implementation. Instead, it just says that the web application's main class should inherit from Global type defined in the F# part of the solution. When the application starts, it invokes the Start method defined in F#. The actual implementation is given in the Global.fs file:
namespace FSharpWeb.Core
open System.Web.Mvc
open System.Web.Routing
/// F# record that can be used for creating route information
type Route =
{ controller : string
action : string }
/// Represents the application and registers routes
type Global() =
inherit System.Web.HttpApplication()
static member RegisterRoutes(routes:RouteCollection) =
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
routes.MapRoute
( "Default", "{controller}/{action}",
{ controller = "Main"; action = "Index" })
member this.Start() =
AreaRegistration.RegisterAllAreas()
Global.RegisterRoutes(RouteTable.Routes)
The listing first declares a record named Route. The record is used to specify the controller and the mapping action. The MVC Framework examines the names of the fields of the record, so the names are required to be controller and action. When creating a mapping that also includes an argument (such as id), another record type with an additional member needs to be declared.
Next, the listing defines a Global class that represents the application (and is used from Global.asax). The type inherits from ASP.NET HttpApplication object and defines two methods that initialize routing.
The Start method is called from the C# code. It first invokes RegisterAllAreas method, which is required by ASP.NET MVC and then calls the static helper method to add route specifications to a global collection. The RegisterRoutes method first calls IgnoreRoute (to disable routing for some special requests) and then creates a single route using MapRoute.
The first argument of MapRoute specifies a unique name of the route. The second argument is more interesting. It specifies a pattern of URLs handled by the route. When the URL looks like /Main/Hello, the route will be used with Main as the name of the controller and Hello as the action. The last argument is the value of the record (declared earlier) that specifies the default values for the route.
Summary
This tutorial explained the architecture of a simple ASP.NET MVC 3 web application that uses C# and the Razor view engine for the front-end and F# for the back-end part of the application. The article first looked how to create a sample solution using an online template and then explained the individual components of the application.
Web applications created using ASP.NET MVC consist of three types of components. A model (implemented in F#) can be any module or collection of types that provide access to data or contain business logic. Controllers (also implemented in F#) specify how to handle requests from the user. Finally, views define the user interface and are implemented using a mix of HTML and embedded C# snippets (in the case of Razor templates).
The sample discussed in this tutorial used one particular online template that generates a single F# library and a single C# web project. However, the Visual Studio Gallery contains a large number of other templates that also provide excellent starting points when developing F# applications.
Additional Resources
This tutorial demonstrates how to create a simple web application using an online template. For more information about developing web applications in F# and working with data, see the following tutorials:
To download the code snippets shown in this article, go to https://code.msdn.microsoft.com/Chapter-5-Bulding-Data-ec639934
See Also
This article is based on Real World Functional Programming: With Examples in F# and C#. Book chapters related to the content of this article are:
- Book Chapter 9: “Turning values into F# object types with members” explains how to use object-oriented features of the F# language. This is an important topic for web development because it explains how to mix the functional programming style with the object-oriented approach required by ASP.NET.
The following MSDN documents are related to the topic of this article:
F# Empty Web (MVC3 Razor)—the F# project template used in this tutorial (at Visual Studio Gallery)
ASP.NET MVC 3 contains more information about the MVC Framework as well as downloads and various sample applications.
Previous article: Overview: Building Data-Driven Websites
Next article: Tutorial: Creating a News Aggregator