How to Host an ASP.NET Application with Mono

From Logic Wiki
Jump to: navigation, search


Mono Project Web Page

[1]

Part 1: Downgrading from .NET Framework 4.5 to 4.0

If you want to run .NET programs on Mac and Linux environments, Mono is making this possible and their latest 3.12.0 release is a great indicator of the possibilities that Mono is bringing to .NET community.

This is the first of a three part series to detail how to use Mono to host ASP.NET applications on Linux and Mac OSX. We are using Visual Studio Community 2013 to develop our sample ASP.NET MVC WebApi application. Visual Studio Community 2013 defaulted to .NET framework 4.5 when we created the new project. We quickly realized that Mono 3.12.0 does not support .NET framework 4.5. It does support .NET framework 4.0 and this is where our fun began.

STEPS TO DOWNGRADE AN ASP.NET MVC APPLICATION FROM 4.5 TO 4.0 .NET FRAMEWORK

As mentioned above, Mono 3.12.0 does not work with .NET framework 4.5, so we needed to downgrade our application to use .NET framework 4.0. These are the steps we performed to downgrade our application:

  • Run your application and ensure it is working with the .NET Framework 4.5
  • Right click your MVC project and Select Properties
  • Under Application change the Target Framework to .NET Framework 4
  • Select Yes to confirm the Target Framework change
  • Close and reopen your project
  • Run these commands in the Package Manager Console
Uninstall-Package Microsoft.AspNet.Identity.Owin
Uninstall-Package Microsoft.AspNet.Identity.EntityFramework
Uninstall-Package Microsoft.AspNet.Identity.Core
Uninstall-Package EntityFramework
Uninstall-Package Microsoft.Owin.Security.Twitter
Uninstall-Package Microsoft.Owin.Security.OAuth
Uninstall-Package Microsoft.Owin.Security.MicrosoftAccount
Uninstall-Package Microsoft.Owin.Security.Google
Uninstall-Package Microsoft.Owin.Security.Facebook
Uninstall-Package Microsoft.Owin.Security.Cookies
Uninstall-Package Microsoft.Owin.Security
Uninstall-Package Microsoft.Owin.Host.SystemWeb
Uninstall-Package Microsoft.AspNet.WebApi.Owin
Uninstall-Package Microsoft.Owin
Uninstall-Package Microsoft.AspNet.WebApi.HelpPage
Uninstall-Package Microsoft.AspNet.Mvc
Uninstall-Package Microsoft.AspNet.WebPages
Uninstall-Package Microsoft.AspNet.Razor
Uninstall-Package Microsoft.AspNet.Web.Optimization
Uninstall-Package Microsoft.AspNet.WebApi
Uninstall-Package Microsoft.AspNet.WebApi.Webhost
Uninstall-Package Microsoft.AspNet.WebApi.Core
Uninstall-Package Microsoft.AspNet.WebApi.Client
Uninstall-Package Owin
  • Save your project
  • Close and reopen Visual Studio
  • Reopen the project
  • Run these commands in the Package Manager Console
Install-Package Microsoft.AspNet.Razor -Version 2.0.30506
Install-Package Microsoft.AspNet.Mvc -Version 4.0.30506
Install-Package Microsoft.AspNet.Web.Optimization -Version 1.1.3
Install-Package Microsoft.AspNet.WebApi -Version 4.0.30506
Install-Package Microsoft.AspNet.WebApi.Client -Version 4.0.30506
Install-Package Microsoft.AspNet.WebApi.Core -Version 4.0.30506
Install-Package Microsoft.AspNet.WebApi.HelpPage -Version 4.0.30506

You will be prompted on whether you want to overwrite _ViewStart.cshtml when you install the Microsoft.AspNet.WebApi.HelpPage. Select option A to overwrite _ViewStart.cshtml. Open packages.config and search the file for targetFramework="net45". Replace any references with targetFramework="net40"

I got an error that stated I needed to re-install Newtonsoft.Json. I was able to remedy the error by running this in the Package Manager Console

Install-Package Newtonsoft.Json

Now that you have cleaned up the NuGet package references it is time to clean up the code that came with the WebAPI 2.2 .NET Framework 4.5 template.

  • Delete the following files:
Models > IdentityModles.cs
App_Start > IdentityConfig.cs
App_Start > Startup.Auth.cs
App_Start > Startup.cs
Providers > ApplicationOAuthProvider.cs
Controllers > AccountController.cs
Controllers > ValuesController.cs
Results > ChallengeResult.cs
Models > AccountBindingModels.cs
Models > AccountViewModels.cs

We need to update the code in App_Start > WebApiConfig.cs.

Remove

using Microsoft.Owin.Security.OAuth; 

Remove

config.SuppressDefaultHostAuthentication();

Remove

config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

Remove

config.MapHttpAttributeRoutes();

We need to update the Global.asax.cs code:

//GlobalConfiguration.Configure(WebApiConfig.Register);
WebApiConfig.Register(GlobalConfiguration.Configuration)

If you try to run your application now, you will see this error:

Parser Error Message: An error occurred creating the configuration section handler for system.web.webPages.razor/host: Could not load file or assembly 'System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

To fix this error we need to update the versions referenced in the Views > Web.config file as follows:

<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup> 

...

<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

Now your application should run and the Home view should render. Let's add a new WebApi controller to ensure that we can invoke the RESTful service.

Add a new sample WebApi controller named TestController.cs Start your application and note the port used on localhost Test the GET http method call by going to http://localhost:<<port>>/api/test. You should see this response:

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><string>value1</string><string>value2</string></ArrayOfstring>


Part 2: Hosting on Mac OSX

Keep in mind that Mono doesn't currently support .NET Framework 4.5, so follow the instructions in Part 1 of this series if you need to downgrade to .NET Framework 4.0.


ENVIRONMENTS AND SOFTWARE VERSIONS USED

  • Operating Systems - Windows 8.1, Mac OSX 10.9.5, Ubuntu Server 14.04 LTS (HVM)
  • Mono 3.12.0
  • Visual Studio Community 2013 Version 12.0.31101.00 Update 4
  • ASP.NET MVC 4
  • Apache 2.4
  • VMware Fusion 7.1.1

We are using an iMac as our development machine. It is running OSX 10.9.5 and has VMware Fusion installed. We have a Windows 8.1 64-bit VM that we access through Fusion. The Windows 8.1 VM has Visual Studio installed and that is where we wrote our ASP.NET MVC WebApi application. Visual Studio Community 2013 defaulted to .NET framework 4.5 when we created the new project. We quickly realized that Mono 3.12.0 does not support .NET framework 4.5. It does support .NET framework 4.0 and this is where our fun began. Follow the instructions in Part 1 of this series if you need to downgrade to .NET Framework 4.0.


INSTALLING MONO ON MAC OSX

Now that we have a ASP.NET MVC 4.0 application we can deploy that code to a Mac OSX machine and ensure that Mono will allow that application to run. We followed the Install Mono on Mac OSX instructions on the Mono site.

We installed the .pkg and followed the installation wizard. Then, we tried to run through the Hello World examples to ensure they were working. All of the sample programs ran without error except for the Gtk# Hello World example. We noticed this error:

System.DllNotFoundException: gtksharpglue-2
at (wrapper managed-to-native) Gtk.Container:gtksharp_gtk_container_get_focus_child_offset ()
at Gtk.Container..cctor () [0x00000] in <filename unknown>:0

We were able to fix this error by adding the following lines to the /Library/Frameworks/Mono.framework/Versions/3.12.0/etc/mono config file:

<dllmap os="osx" dll="glibsharpglue-2" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libglibsharpglue-2.so" />
<dllmap os="osx" dll="gthread-2.0.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgthread-2.0.0.dylib" />
<dllmap os="osx" dll="gthread-2.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgthread-2.0.dylib" />
<dllmap os="osx" dll="glib-2.0.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libglib-2.0.0.dylib" />
<dllmap os="osx" dll="glib-2.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libglib-2.0.dylib" />
<dllmap os="osx" dll="glibsharpglue-2" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libglibsharpglue-2.so" />
<dllmap os="osx" dll="gtksharpglue-2" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgtksharpglue-2.so" />
<dllmap os="osx" dll="gobject-2.0.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgobject-2.0.0.dylib" />
<dllmap os="osx" dll="gobject-2.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgobject-2.0.dylib" />
<dllmap os="osx" dll="gtk-quartz-2.0.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgtk-quartz-2.0.0.dylib" />
<dllmap os="osx" dll="gtk-quartz-2.0" target="/Library/Frameworks/Mono.framework/Versions/Current/lib/libgtk-quartz-2.0.dylib" />

RUNNING ASP.NET MVC 4.0 APPLICATION ON MAC OSX

With the sample programs working it was time to try out my MVC application. We deployed the code from the Windows 8.1 VM to a new folder on the iMac. Then, opened terminal and ran this:

xsp4 --root <<parent folder path to the MVC bin folder -- do not include /bin in path>> --port 9000

While the xsp server is running you can test your application using http://localhost:9000/api/test url. Replace "test" with the name of your controller. PART 3 is not published yet : follow the link for it http://www.bloomspire.com/blog/2015/3/6/how-to-host-aspnet-applications-on-linux-part-2-hosting-mac-osx