How to Host an ASP.NET Application with Mono - Part 1: Downgrading from .NET Framework 4.5 to 4.0

At Bloomspire we are constantly brainstorming on what we can bring to the marketplace to improve business efficiency.  We are in the process of prototyping a new product that will require a REST service.  We have a lot of experience with .NET so we chose to implement a Web Api ASP.NET MVC project for our RESTful HTTP service.  We could easily host one of these solutions on a Windows environment, but we wanted to try hosting on Linux just for fun.

For the past few months we have been anxiously anticipating the day when you can run .NET programs on Mac and Linux environments.  We are living in exciting times for .NET developers.  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>

Please stay tuned for Part 2 of this topic where we explore hosting an ASP.NET application on Mac OSX.  We hope this blog post helps if you ever run into the situation where you need to downgrade your applications.

@bloomspire