2012-08-14

How to Add WebSharper JavaScript to an ASP.NET MVC Web App

WebSharper can be used to write JavaScript for your ASP.NET MVC web application. I’m going to demonstrate an easy way to add the JavaScript output from WebSharper to your existing C# ASP.NET MVC Web Application.

A couple of days ago, I deployed a “Hello World” MVC app in the clouds. The source code is on GitHub. Take a look at this evening’s commits. I’m going to add the Factorial function from the manual.  Add a new F# Library project to your solution. I used “HolaMundo”, so the JavaScript file will end up being HolaMundo.dll.js. Add a reference to the new project from the MVC project. Use NuGet to add “WebSharper” to both projects. Unload and edit both project files.

To MvcApp.csproj, I added these two lines just before </Project>

<Import Project="$(SolutionDir)\WebSharper.targets" />
<Import Project="$(WebSharperHome)\IntelliFactory.WebSharper.Web.targets" Condition="Exists('$(WebSharperHome)')" />

To HolaMundo.fsproj, I added these two lines just before </Project>

<Import Project="$(SolutionDir)\WebSharper.targets" />
<Import Project="$(WebSharperHome)\IntelliFactory.WebSharper.targets" Condition="Exists('$(WebSharperHome)')" />

When you reload the projects, you will notice several references added to each project. The Web.targets makes it so that WebSharper outputs the JavaScript files to the Scripts folder. Here is the F# code HolaMundo.fs that will get compiled to JavaScript:

namespace Hola

module Mundo =

    open IntelliFactory.WebSharper

    open IntelliFactory.WebSharper.JavaScript

 

    [<JavaScript>]

    let rec Factorial n =

        match n with

        | 0 -> 1

        | n -> n * Factorial (n - 1)

 

    [<JavaScript>]

    let AlertFactorial n =

        let fact = Factorial n

        "Factorial(" + n.ToString() + ") = " + fact.ToString() |> Alert

The last thing to do is to add the JavaScript to the web page. I added IntelliFactory.JavaScript.Runtime.js to the Scripts folder manually. I modified Index.cshtml to include the JavaScript file and initialize Websharper JavaScript. It is then easy to call the JavaScript functions that were written in F#. Index.cshtml:

@{
    var title = ".NET Web App in the Clouds";
    ViewBag.Title = title;
}
@section head
{
    <script src="@Url.Content("~/Scripts/IntelliFactory.JavaScript.Runtime.js")"></script>
    <script src="@Url.Content("~/Scripts/HolaMundo.dll.js")"></script>
    <script>IntelliFactory.Runtime.Start();</script>
}
<h2>Hello World from a @title</h2>
<p><a href="#" onclick="Hola.Mundo.AlertFactorial(7); return false;">Run Factorial(7)</a></p>

Ugh. The AppHarbor website will have to wait a little while. It is not deploying to AppHarbor because $(WEBSHARPER_HOME) doesn’t appear to get set. But, everything should work locally for you if you git clone the code. In the meanwhile, I put it on Elastic Beanstalk and Azure:

It is a very simple JavaScript functionality, but hopefully this helps with project setup.

2012-08-15 Update

The code now builds and deploys on AppHarbor. To get it running there, I had to commit the msbuild targets for Websharper that were downloaded with NuGet as mentioned here. It isn’t ideal, but not a major issue either. Today’s latest commit is recommended for building it and trying it out.  It took it off Elastic Beanstalk. Here it is running on AppHarbor: