Hands On Microsoft loves Linux – but coding and deploying an ASP.NET Core application for the open-source OS comes with a bit of friction compared to using Windows.
Microsoft announced .NET Core in 2014, an open-source and cross-platform fork of the hitherto Windows-only .NET Framework. Two years later it reached version 1.0 and today the current version is version 2.2, along with ASP.NET Core 2.2 and Entity Framework 2.2.
Still in preparation is .NET Core 3.0 – now "very close to being feature complete", according to program manager Richard Lander, with final release expected later this year. Next year we should see .NET 5.0, a major release which Microsoft hopes will unify the .NET platform.
This means we have now had three years of production-ready .NET Core, which indicates a reasonable level of maturity. Cross-platform is a key feature, and there are obvious attractions to deploying to Linux rather than Windows, including options for licence-free servers.
But how easy is it to fire up Visual Studio 2019, and then build and deploy a web application to Linux? It is the kind of thing you might want to do for a quick prototype, with the benefit of ubiquitous Linux hosting from numerous providers.
Visual Studio offers a range of frameworks for ASP.NET Core web applications, depending on which components of Microsoft's sprawling IDE you have chosen to install. These include the old ASP.NET MVC (but not the even older web forms, which is exclusive to the .NET Framework), as well as Angular, React.js, or React.js with Redux (a library which stores and updates state).
There are a couple of points to note. One is that if you use one of the React options you are creating a dependency on Node.js. Further, while these are fine frameworks, there is not a lot of help from Microsoft's official documentation on how to use them. There is of course a ton of help from the React community, but you will find that not so many of them use Visual Studio. In fact, you may be better off using Visual Studio Code, which is more widely used.
The path of least resistance, then, is an ASP.NET MVC application. Since ASP.NET MVC is a Microsoft invention, it is much better documented for users of Visual Studio.
Another point, though: if you check one of the authentication options, Visual Studio will generate some useful code for user management – and your application is bound to need user management.
Less obvious is that if you opt for "Individual user accounts", which means a dedicated database for the application to use, the application will be configured for SQL Server. Not a problem, perhaps, if you intend on deploying to Azure, but less than ideal if you have in mind a cheap Linux host. Something like MySQL or SQLite is a more convenient choice. You will have to modify the code to use a different database manager.
Microsoft's Visual Studio templates push you strongly towards Entity Framework Core (EF Core), the cross-platform version of the company's ORM (Object-relational mapping) layer. If you are coding a data-intensive application where database performance is critical, it might not be the best choice. On the other hand, it is convenient for many use cases using small databases. It is a good choice for a prototype.
If you choose Sqlite, there is a handy NuGet package called Microsoft.EntityFrameworkCore.Sqlite. MySQL, on the other hand, is more troublesome. The official Oracle provider is described in this table and you will notice that the latest version of Oracle's connector only supports EF Core 1.1. There are other options, such as Pomelo.EntityFrameworkCore.MySql, which has a reassuring 2.47 million downloads.
The Pomelo library for MySql is more widely compatible than Oracle's offering
In this case we are going the MySQL route. On Windows 10, you can either install the Windows version of MySQL, or use the Windows Subsystem for Linux and run it there. Either way, create a database, create a user with rights to that database, and then you can add a connection string to the ASP.NET application. Add the connection string in appsettings.json. Then you can go along to Startup.cs and modify
options.UseMySql and the name of your new connection string. The UseMySql option appears magically after installing the Pomelo package.
There is a slight problem, which is that EF Core may have generated Migrations for your user database. Migrations are used in EF Core to create and then update the database structure. You can delete the existing migrations, which are specific to SQL Server. Then open up the package manager and enter:
If all goes well, your user database is created in MySql. The application will have a functional registration and login system. If EF Core is working, you have all you need to build a forms over data application. ASP.NET MVC will scaffold CRUD (Create, Retrieve, Update, Delete) functionality for you, if you add classes in the Models section of the code.
What about deploying to Linux, though?
There are a few options. If you are happy with a Docker container, right-click the project, add Docker support, and you can select Linux as the target OS. It is a bit black-box, but Visual Studio and Docker will get you a working container.
This will not help you deploy to any old Linux VM, though. For that, you will need to hit Publish on the Build menu and pick Publish to a Folder. Click Advanced, and you can select Linux-x64 as the target runtime.
Publish settings for an ASP.NET Core application
You can also choose between Framework Dependent or Self Contained. This is a choice between installing and maintaining the .NET Core runtime centrally on the server, or deploying the entire runtime with the application – around 112MB in this case.
There are pros and cons. The self-contained deployment is simpler and avoids potential incompatibilities with what is installed centrally, but wasteful of disk space and requires servicing by you. The Framework Dependent deployment will get you visiting the .NET Core download page in many cases, or else configuring Microsoft repositories so you can use
apt-get or similar.
There is another complication, which is that .NET Core has its own built-in web server, called Kestrel, which may or may not need to be behind a reverse proxy depending on your configuration; using a reverse proxy is recommended. You also have to set up a service so that the application runs automatically. It is not like a LAMP (Linux, Apache, MySQL, PHP) application where your application will run provided PHP itself is running.
It works! Registering a user with MySql and ASP.NET Core
The good news is that with this configured, our demo app worked fine on Debian 8 – though we never got it working with the pre-configured www-data user for some reason, creating a new user instead. Performance is good even on a tiny VM.
It must be said, though, that there is friction in going the Linux route with Visual Studio, from the templates that steer you towards SQL Server, to the niggles around using MySQL, and working out the right steps for your chosen Linux target.
Using Microsoft Azure and the Linux app service or another means of running Docker containers simplifies matters in some ways, and complicates them in others.
Does it matter? It is no big deal at all for an application of significant size, but for kicking-the-tires prototypes it does make a difference. What you discover is that deploying to Windows is both easier and better documented, which may be how the company wants it, but on the other hand, may hold the technology back. ®