ASP.NET web applications in F#
More recent article available
This article is no longer up-to-date. Although the techniques described in the article might still work (with a lot of adjustments to the newer version of F#), it is now recommended to use a different approach. Note that CodeDOM provider is now a part of F# Power Pack. For more recent information see:CodeDOM and providers
CodeDOM (Code Document Object Model) is set of objects (located in System.CodeDom
namespace) that can be used
for representing logical structure of .NET source code. For example you can use CodeTypeDeclaration
class
to represent class declaration or CodeAssignStatement
to represent assignment in the body of method. CodeDom
is language independent and CodeDOM structure can be translated to source code in specified language using code generator
(class that implements ICodeGenerator
namespace). The CodeDOM structure can be also compiled to assembly
using code compiler (implementation of ICodeCompiler
interface). Microsoft provides several code providers
with .NET Framework (for C#, VB.Net, JScript and C++), but you can add your own by by implementing previously mentioned
interfaces.
In the .NET Framework, CodeDOM is used for automatic code generation. For example when you add web reference to your project, the wrapper class that calls web service is generated using CodeDom. Some more examples are typed dataset (generated from XSD files) and generator for data layer in the upcoming LINQ project, but the most interesting use for CodeDOM for me is in ASP.NET 2.0.
Typical ASP.NET web page consists of several aspx
/ascx
files and associated code behind files
written in one of the .NET languages. When building web page, ASP.NET uses CodeDOM for building aspx
/ascx
files. It parses these files and generates according CodeDOM structure. For example <asp:Button id="btn" runat="server" />
declaration is translated to declaration of btn
member and code that assigns new instance of
Button
object to this member. This generated structure is compiled to .NET assemblies using code compiler
and the web page is ready to use. If you use any in-line code in ASP.NET page, it is included in the
CodeDOM structure as literal, which means that if the generated CodeDOM is compiled using C# code compiler,
it can contain literals only in C# language (because you can't mix languages in one source file).
ASP.NET and F#
In ASP.NET 1.1 you could compile code behind files using different compiler than the rest of the page
(source generated from aspx
/ascx
). This method is used by ASP.NET in F# demo by
Robert Pickering [1]. The more complex approach that is available in ASP.NET 2 is
to write CodeDomProvider
implementation for F#. This makes it possible to write F# in-line code
in web pages and this method allows you to fully benefit of ASP.NET compilation model (for example you can
use Publish Web Site command in Visual Studio).
FSharpCodeProvider & AspNetFsharpCodeProvider
I wanted to implement CodeDomProvider for the F# language, for the reasons mentioned above. Currently, I'm
presenting version of provider that is able to compile ASP.NET pages quite well, however I implemented only features
required by ASP.NET, so the provider is not complete. There are also some problems that has to be handled
specially (for example, F# doesn't support partial classes), so apart from standard provider (FsharpCodeProvider
),
I also implemented AspNetFsharpCodeProvider
that contains several 'hacks' for ASP.NET.
How to use it?
Important: For correct functionality of F# CodeDOM compiler, you have to modify your
system variable PATH to include 'bin' directory of your F# installation folder. This is because, code compiler
uses fsc.exe
for compilation and there is no simple way for finding where the F# is installed.
The most simple way to start creating ASP.NET web sites in F# is to use VS.NET project template that you can find in the downloads section. Using this template, you can create web page that is already configured to use F# language. After installation, select File - New - WebSite.. and in the dialog select language 'Visual C#' (it is not possible to add another language AFAIK) and than select 'F# WebSite' template.
If you want to configure ASP.NET web site to use F# code provider manually, you have to do the following steps.
First modify the web.config
file to include the following elements in the compilation
section:
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true"> <compilers> <compiler language="F#;f#;fs;fsharp" extension=".fs" type="EeekSoft.FSharp.CodeDom.AspNetFSharpCodeProvider, fscodeprovider"/> </compilers> </compilation> </system.web> </configuration>
This adds reference to the assembly that contains the
AspNetFShaprCodeProvider
class and it configures ASP.NET to use F# code generator for aspx
files which Language
attribute is set to "F#". When this is done, you can add F# page by adding
aspx
and code behind fs
files. In the Page
directive, set the
Language
attribute to "F#" and define the code behind class in the fs
file.
The following example shows code behind class for simple web page (that contains one button with ID set
to btnOk
):
namespace FSharpWeb open System;; open System.Web.UI.WebControls;; // Code behind class declaration type Default = class inherit System.Web.UI.Page as base // Declaration of button control val mutable btnOk : Button; // All fields must be initialized in constructor new() = { btnOk = null; } // Set text of button in onload override this.OnLoad (e) = btnOk.Text <- "Hello world!"; base.OnLoad (e); end;;
There is still one little difference when compared with C#, which is that it is required to
manually declare all controls (with ID) that are on the page (btnOk
in this example).
This is because F# doesn't (currently) support partial classes and so the partial class with
control declarations that is generated by ASP.NET is dropped by the CodeDOM provider. The rest is
very similar to how you develop ASP.NET pages in other languages; you can see more examples if you
download attached example application. More information regarding object oriented programming in F#
can be found in F# manual available at F# homepage [3].
Other CodeDom provider notes
As I mentioned earlier, the CodeDOM generator I created is still very limited and it is tested
only with ASP.NET. You can find list of not implemented features in the release notes (see downloads).
In the future, I'd like to extend it to support generating code for accessing web services too
(code is generated using wsdl
tool). If you have any interesting idea, how it could be
used or if you have any other comments, ideas, bug fixes, etc., please let me know (at
tomas@tomasp.net).
Downloads & links
- F# CodeGenerator including sources and sample F# Web application (ZIP, 174kB)
- F# WebSite template for Visual Studio 2005 (VSI, 65.7kB)
- Release notes (known issues and not implemented features) [^]
- [1] F# Resources - Aspf Demo [^] - StrangeLights.Com
- [2] Sample CodeDom Provider [^] - Reference CodeDomProvider implementation
- [3] F# [^] - Microsoft Research
Published: Sunday, 13 August 2006, 9:06 PM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: web, f#