Run C# code in browser using web assembly via mono-wasm

Stampa

Javascript is the language of the moment. An interesting new project is born every week.

But, what is WebAssenbly? From the official website we read:

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

WebAssembly is a technology that creates a virtual machine in the browser where it is possible to execute code not designed for the web
Even more interesting for .NET programmers, the Mono Project has developed a virtual machine in WebAssembly for the Mono runtime, with which it's possible to run C# programs natively by the browser.
There is another technology that allows you to run C# code in the browser. It's Blazor and belongs to Microsoft.
Blazor is a frontend framework and allows you to develop a full C# application that runs natively by the browser.
Mono-WASM allows you to create even a single piece of the application and to request it from Javascript code.

Let's try using Mono-WASM
In this basic tutorial we create a simple C# library and run it in the browser, making it interact with the HTML page using Javascript. Let's get the necessary tools first.

Download and install Mono SDK.
https://www.mono-project.com/download/stable/

Get the latest build of Mono-WASM from this site
https://jenkins.mono-project.com/job/test-mono-mainline-wasm/

Download sdks/wasm/mono-wasm-###########.zip and extract it, for example in C:\mono-wasm

After installation, add a path to the bin directory of mono (C:\Program Files\Mono\bin) and Mono-WASM (C:\mono-wasm) directory in environment paths variable.
Make sure you can access mono and Mono-WASM directly from your terminal.

Now create a folder to use for the project, for example

C:\Test

Create a Sample.cs file with a simple C# class that includes a static method

using System;

public class Sample
{
public static string Hello(string Name)
{
return "Hello " + Name;
}
}

We also create an index.html file

<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello WASM</title>
</head>

<body>
<form>
<textarea id="output" rows="10"></textarea>
<button type="button" id="button" onclick="App.onClick">Run WASM</button>
</form>

<script type='text/javascript'>
let that = this;
var App = {
onClick: function () {
that.output.value = "Please wait";
that.output.value = that.execute("Noos");
},

init: function () {
that.execute = Module.mono_bind_static_method("[Sample] Sample:Hello");
that.output = document.getElementById("output");
that.button = document.getElementById("button");
that.button.disabled = false;
}
};

document.getElementById("button").addEventListener("click",App.onClick);
document.body.addEventListener("load", App.init);
</script>
<script type="text/javascript" src="/mono-config.js"></script>
<script type="text/javascript" src="/runtime.js"></script>
<script async type="text/javascript" src="/dotnet.js"></script>
</body>

</html>

Bound a static method of .NET to a JS variable:

var execute = Module.mono_bind_static_method("[Sample] Sample:Hello");

Module is an object that is injected by mono.js files into the page. This object has many methods but one of the most useful ones is the mono_bind_static_method. With this method, you can bind any static methods from .NET to the JS world and execute it like a simple JS function.

Using command prompt, compile the code in NET assemblies with Mono

mcs /target:library -out:Sample.dll /noconfig /nostdlib 
/r:C:\mono-wasm\wasm-bcl\wasm\mscorlib.dll
/r:C:\mono-wasm\wasm-bcl\wasm\System.dll
/r:C:\mono-wasm\wasm-bcl\wasm\System.Core.dll
/r:C:\mono-wasm\wasm-bcl\wasm\Facades\netstandard.dll
/r:C:\mono-wasm\wasm-bcl\wasm\System.Net.Http.dll
/r:C:\mono-wasm\framework\WebAssembly.Bindings.dll
/r:C:\mono-wasm\framework\WebAssembly.Net.Http.dll Sample.cs

As you can see with -out we defined the output name of our assembly. At the end of the command, you should add the CSharp files you want to compile. Other assemblies are inside the Mono-WASM directory that is referenced for compilation.
If you compiled the code successfully, Sample.dll assembly should be created.

So we can publish the library for web assembly using Mono-WASM

mono C:\mono-wasm\packager.exe --copy=always --out=.\publish --asset=.\index.html Sample.dll

This command run packager.exe which is a tool from Mono that publishes your assembly with all of the requirements. The packager will create a folder called publish, and it will copy things in it.

mono.js, mono-config.js, and runtime.js are mono bindings for JavaScript.
mono.wasm is the Mono .NET runtime for web assembly.
In managed folder you will see lots of DLL assembly files including your Sample.dll.
You can copy content of publish folder on your static web server
Run it and navigate to the URL.