.NET Framework web development on Mac with Mono
When it comes to developing an ASP.NET MVC application for .NET Framework on your non Windows dev machine, you can make use of Mono Framework. A word of caution that Mono is no longer developed since .NET 5 was released. However, if your application targets .NET Framework version 4.8, you can still develop and run your application on Mac or Linux using Mono.
Visit the mono download page and download the latest release for your Operating System. As the title of the blog post suggests, I am going to be using a Mac. At the time of writing, the stable version of Mono is 6.12.0.
Complete the installation following the guide on the website. Once its complete,
Mono command line tools will be available at the path
/Library/Frameworks/Mono.framework/Versions/Current/Commands. You can
optionally add this path to your
$PATH environment variable.
I’ll be making use of
Makefile in order to write my build scripts.
But, you can choose your own preferred tool. Create a
Makefile at the root of
your repository / project structure.
Next, we will need a build task in the
Makefile that will compile the project
msbuild = "/Library/Frameworks/Mono.framework/Versions/Current/Commands/msbuild" build: $(msbuild) ./ExampleWebsite.sln
Notice that on the first line, I set a variable for
msbuild which points to
msbuild commandline tool that was added by the Mono Framework
installation. I then refer to this variable in the build task. If you’ve saved
the path to Mono installation location in your environment variable, then you
don’t need to declare a variable and can invoke
msbuild command directly from
build task. Which will be a good idea if the
Makefile and task are going to be
used from a Windows machine as well. And
msbuild command is also resolved
on that machine.
At this stage, executing the build command
make build will error with the
message that NuGet packages are missing. So, lets add a new task to restore the
restore: $(msbuild) ./ExampleWebsite.sln /t:restore /p:RestorePackagesConfig=true build: restore $(msbuild) ./ExampleWebsite.sln
/t:restore indicates to
msbuild that we want to invoke the
/p:RestorePackagesConfig=true is required if the project uses
packages.config file for managing dependencies. You can omit this argument if
.csproj file is using the newer SDK style file. You can also see I’ve
specified that the build task depends on the new
restore task. Therefore,
calling the build task will first run the
Running the Website
Mono comes with a command line tool called
xsp4 that can be used to run a web
application. XSP is the Mono ASP.NET Web Server. The process provides a
minimalistic web server which hosts the ASP.NET runtime and can be used to test
and debug web applications that use the
System.Web facilities in Mono.
is not intended to be used as your production web server. Unless its used as a
means for integrating with a production web server such as Apache.
We will call the new task
xsp4 = "/Library/Frameworks/Mono.framework/Versions/Current/Commands/xsp4" run_web: build $(xsp4) --verbose --applications=/:./ExampleWebsite
run_web task has a dependency on the
build task. I am also referring
xsp4 tool via a variable that points to the actual location of the tool.
--verbose flag prints extra mesages to the output which are useful for
--applications argument allows you to provide a list of
virtual and real directory for all applications we want to manage with this
server. The virtual and real directories are seperated by a colon. In our case,
we only specify 1 application. At the root (
/) virtual directory that is
mapped to the relative real directory where the website project is located.
I suggest first reading ASP.NET getting started page on mono project website to learn more about the web server. There are lots of other arguments that you can pass to the tool. Which are documented on the xsp4 manpages.
If you run the new task
make run_web, there will be a website running on port
localhost which you can browse to. As the task output suggests, you
Return key to stop the web server running.
If you have team members using more than one development operating systems, it will be a good idea to make sure your Continuous Integration pipeline builds for all the different Operating Systems. Because it will be easy for one of the team members to introduce a change that breaks the application for others.
Try to move away from .NET Framework as soon as possible into .NET 7 which is latest at the time of writing as they have cross platform support built in.