Creating a Development Container for ASP.NET Core MVC with Entity Framework and SQL Server

The purpose of this document is to describe the steps that can be used to create a Development Container for ASP.NET Core MVC with Entity Framework and SQL Server.

Some advantages to doing it this way are:

    • Different developers can have different operating systems and still collaborate on the same web application
    • Extensions added in Visual Studio Code are added to the container so developers can have the same IDE experience as well
    • Dependencies are managed inside the container instead of the local developer’s computer

Prerequisites

This article assumes that the reader already has Docker desktop setup on their computer and that they have Visual Studio Code installed as well.

Instructions

ASP.NET Core, Entity Framework, and SQL Server are very common components in a web application. We will be creating a container for the web server, and a container for the database server. On a high level the steps are:
    1. Create a new folder on your computer
    2. Add the remote container files from Visual Studio Code
    3. Reopen the folder in Visual Studio Code to have it use the container
    4. Explore the container
    5. Issue commands in the container to start building the project
    6. Run the project
    7. Demonstration of how to do entity framework migrations
    8. Things to be aware of when sharing the git repository across different operating systems

Create a new folder on your computer

This is self-explanatory. Just create a folder anywhere on your computer. For the purposes of this demonstration, I will call it “mvcapp1”, and on my computer I have it in C:\\Users\\Me\\source\\repos\\.

After the folder has been created open it up in Visual Studio Code.

Add the remote container files from Visual Studio Code

 

      • Click on View -> Command Pallet or press Ctrl+Shift+P to bring up the Command Pallet
      • In the Command Pallet type “Remote Containers” and select the “Remote-Containers: Add Development Container Configuration Files…”
      • Select the “C# (.NET) and MS SQL” option
      • In this demonstration we will select .net 6, and the lts version of nodejs.
      • We will also select the Azure and GitHub CLIs

Reopen the folder in the container

Once these files have been added you should get a prompt in the bottom right hand corner of your screen with a prompt like this:

Click the Reopen in Container. Did you miss it? No problem. Go to the Command Pallet again and select “Remote-Containers: Reopen in Container”
You will get a little notice like this in the bottom right-hand corner of the screen as it boots the container up
If you launch your Docker desktop you will also see it building / running
As you can tell you have one container for your application, and another container for your database.

Explore the Container

Before we go to much further let’s pause and appreciate what has been done for us and where we are at. In the bottom left hand corner you will notice that we have a green area saying which container this instance of Visual Studio Code is connected to.

Do a CTRL+SHIFT+~ to bring up a terminal. To confirm that we have .net 6 installed type dotnet –info into the terminal.
Notice that we are on Ubuntu as well because that is the operating system for the container that we are in. We can also confirm that git, node, and npm are installed by issuing the following commands:

      • git –version
      • node -v
      • npm -v
This workspace folder is also the equivalent of the folder on your local file system of where you created the new folder at earlier so any files you create on your local computer or in this instance of vscode will be in the folder that you created earlier. Since we installed GitHub CLI and Azure CLI we can also log in to those tools now as well. You can also skip this or do it later. Type gh auth login to login to your github account. Type az login to login with your azure account. Explorer the .devcontainer folder that was created for you. Read over the files inside of there. One particularly interesting piece shows you the connection string information that you need for your SQL server when you configure your app to connect to it. This development container also has a plugin pre-installed that will allow you to interact with this database.
Click that button and then double click on the mssql-container icon and type in the password which you got through reading the .devcontainer files. Once you are connected it will have a green circle icon on it and you can interact with it.

Issue commands in the container to start building the project

This tutorial is going to be specific to ASP.NET Core MVC with Individual Authentication and Entity Framework Code First Approach. Database first approach is still possible, but out of scope for this tutorial. We also recommend getting familiar with the other options aside from the specific ones given in tutorial by using the following command.

      • dotnet new –help
      • dotnet new –list
      • dotnet new [Project Type from –list] –help

We will be taking the following actions:

      • Creating a solution file
      • Creating a gitignore
      • Creating a tools manifest
      • Installing Entity Framework tools
      • Creating an MVC Web Application with Individual Authentication
      • Add the MVC Web Application to the solution file
      • Make small configuration changes to the scaffolded code

These commands are issued inside of the same terminal where we were verifying dotnet, npm, and node versions (CTRL+SHIFT+~) and in the /workspace folder.

In order to create a new solution file issue the following command:

      • dotnet new sln

This will create a workspace.sln file. Rename it to MyApplication.sln (or anything else that you would like) by typing the following command:

      • mv workspace.sln MyApplication.sln

In order to create a new gitignore file execute the following command:

      • dotnet new gitignore

In order to create a new tool-manifest execute the following command:

      • dotnet new tool-manifest

Notice that a new .config\\dotnet-tools.json file is created.
In order to install Entity Framework tool type the following command:

      • dotnet tool install dotnet-ef

This will install Entity Framework locally to your project. Take note of the modification that it made to your .config\\dotnet-tools.json file.

You can also confirm installation by issuing the following command:

      • dotnet ef

In order to create the MVC application execute the following command:

      • dotnet new mvc -au Individual -uld -o MyApplication.Web

The -au Individual paramater makes it use Individual User accounts. The -uld has it use SQL Server instead of SQLLite. The -o portion will create a folder and then create a csproj file inside of that folder. Again see “dotnet new mvc –help” for more information.

Take note of the newly created MyApplication.Web folder that has been created.

In order to add this project to the solution type the following command:

      • dotnet sln add ./MyApplication.Web/

Notice that it says that the project was added to the solution.

Open the appsettings.json file within the MyApplication.Web folder within Visual Studio Code to begin editing it. You will notice that there is a “DefaultConnection” attribute there. That connection string would work on windows. But it will not work for our dev container.

Putting together the information that we get from .devcontainer/devcontainer.json we can conclude that the “DefaultConnection” should actual read as follows:

      • Server=localhost,1433;Database=MyApplication;Trusted_Connection=False;MultipleResultSets=true;User Id=sa;Password=P@ssw0rd

Be sure to save the file after updating the connection string value.

If we look at the scaffolded code we can see that there is a Data\\Migrations folder with a CreateIdentitySchema Migration already in there.

In order to create the database with these tables issue the following command:

      • cd ./MyApplication.Web
      • dotnet ef database update

Notice that it will build your program and create your database.

To confirm that the tables were created go to the SQL Server Button on the far left of Visual Studio Code. Select the mssql-container. Enter the password if prompted and fly out the Database folder and you will see the MyApplication database. Double click on that and the Tables folder to see the tables that were produced by this migration.

Run the Project

Go back to the Explorer within Visual Studio code and double click on the “Program.cs” file. When you do. You should get a prompt like this at the bottom of the screen. Click on “Yes” to add the required assets to build and debug the application.

Missed it? No problem you can also do this: Click the “Run and Debug” tool on the far left side of Visual Studio Code. Then click on the “Generate C# Assets for Build and Debug”
It may not look like it does anything immediately. But press the Run and Debug button and it will start to try and run the application. You will likely get an error this first time that you run it similar to this:
That is Ok. Press the Stop button. Go back to your terminal and type in exactly as the error suggests:

      • dotnet dev-certs https –trust

Then press the play button within the Run and Debug section of Visual Studio code again. When you first run it. You will likely see this in the browser. That is ok. Click on Advanced and then Proceed anyways. The exact text may be different depending on the browser that you are using.

And just like that you are running the web application. To confirm that the debugger is working in Visual Studio code. Go to HomeController.cs and put a break point by pressing F9 on line 18 just before returning the View on the Index action. Refresh the page in the browser. You will notice that your visual studio code will go orange and you can inspect the breakpoint.
Press the continue or step over button to continue the program execution. You may also press F5 or F10 to do the same thing as those buttons represent from the debugger.
I would also recommend that you go through and register your account through the web application. By clicking the Register link in your browser. Follow the steps in the web application to create it. Be sure to click the verify email link. Also practice loging in and out with your account.
Once you are done return to Visual Studio code and inspect the SQL Server area. Browse to the AspNetUsers table. Right click on it and select the Select top 1000 option to see the record that you produced.
Notice the query that it produces and the record that it produced.
You can close the results and query windows, and stop the application. There is no need to save the query either.

Demonstration of how to do entity framework migrations

This is great and all. But now it is time to do your own data. We will start with a very simple example of creating an Item table that just has an Id column and a Title column. We will then use some scaffolding code to create the CRUD functionality for that new customized table. This article does not discuss other architectural topics. You may actually want to do other things like creating multiple class libraries, representing different layers of the architecture. That is still possible using a development container, but is out of scope for this tutorial. To begin we will create an Item.cs class within the Data folder of this project with the following code:

namespace MyApplication.Web.Data;

public partial class Item
{
    public int Id {get; set;}
    public string Title {get; set;} = null!;
}
Next, we will add this class as a DbSet to our DbContext.cs file within the Data folder. The new Context of the ApplicationDbContext.cs file should be as follows.
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace MyApplication.Web.Data;

public class ApplicationDbContext : IdentityDbContext
{
    public virtual DbSet<Item> Items {get; set;} = null!;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}
Return to the terminal and ensure that your terminal is still in /workspace/MyApplication.Web. In the terminal execute the following command:

      • dotnet ef migrations add AddsItemsTable

Take note of the output of the console. Also inspect the Data\\Migrations folder to confirm that a new Migration has been created there. Execute the following command to create the table in the database:

      • dotnet ef database update

Return to the SQL Server section of Visual Studio code and Refresh the SQL Server to see that the new table now exists.

We will now use the dotnet-aspnet-codegenerator tool to scaffold a Controller with Views using Entity Framework.

In the terminal execute the following command:

  • dotnet tool install dotnet-aspnet-codegenerator

Take note of the output. Also take note of the .config/dotnet-tools.json file.

The tool is installed, but the project needs a generator to use. Execute the following command to add this to your project:

  • dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design

Take note of the output of the command prompt. Also take note of your MyApplication.Web.csproj file.

Now that we have the code generator tool and the code generator design nuget package we can create the controller:

  • dotnet aspnet-codegenerator controller -name ItemsController -m MyApplication.Web.Data.Item -dc MyApplication.Web.Data.ApplicationDbContext -scripts -udl -f -outDir ./Controllers

Take note of the output of the console.

Notice that there is a new file in the Controllers folder.

Notice the new folder and files in the Views folder.

Click Here to review an article with more information

Now let’s make a link to the new ItemsController that we just made.

Edit the Views\\Shared\\_Layout.cshtml file add the following code block after the nav item link to the privacy page:

<li class="nav-item">
     <a class="nav-link text-dark" asp-area="" asp-controller="Items" asp-action="Index">Items</a>
</li>
Save the file then go to the run and debug and run the program again. Click the new Items link in your application. Use the CRUD functionality and inspect the SQL Server table as you do.

Things to be aware of when sharing this project with other users

Depending on a windows user’s git configuration they may be setup to automatically change line feeds (LF) to carriage return line feeds (CRLF). In order to ensure that Windows, Linux, and Mac users can all collaborate and use the same dev container. It is recommended to setup the git repository to always use LF. In the workspace folder create a new file called .gitattributes. Add the following code to it:

* text=auto eol=lf
For demonstration purposes this project will be uploaded to github by executing the following command, and going through the prompts of that command. The values that you assign may be different than what we use here. The earlier optional “gh auth login” is now required to go beyond this point of the demonstration.

      • git init
      • git add .
      • git commit -a -m “Initial Commit”
      • gh repo create

          – Specify that you will be pushing an existing repository

          – Path to local repository is indeed “.”

          – Give your repository a name

          – Give your repository a description like for your project

          – Yes, add a remote

          – Origin is just a fine name for the remote

          – Yes, you would like to push commits from the branch

Once that is done you can go to github and see your repository and the code on it. Grab the clone URL. Then in visual studio code click on File and Select Close Remote Connection then close Visual Studio Code. Open a new command prompt and clone the repository to a different folder on your computer. For example:;

      • git clone https://github.com/woodman231/mvccontainerapp1.git cloned1
          – This command will differ depending on your own repository URL

Change directories into your new directory that you downloaded that has a copy of the code. Then enter in a “code .” command to open visual studio code in your new copy of the code. Click the “Reopen in Remote Container” when prompted. It will take some time to launch and will create a different docker instance. Review your docker desktop to confirm. In your new instance of Visual Studio code pull up a terminal and change directories to the MyApplication.Web folder, and execute the following command.

      • dotnet run

You will notice an error regarding the https certificate again since that was not persisted. So execute the following command again as requested:

      • dotnet dev-certs https –trust

Running dotnet run again should no longer be an issue. However, if you attempt to register an account in your web application, it will say that the database has not been initialized yet. Close your browser, and stop the run process in the terminal with a CTRL+C Try and run the following command:

      • dotnet ef database update

You will likely get an error indicating that you will need to run dotnet tool restore in order to make that work. Issue that command as recommended, then try the dotnet ef database update. Things should work much better now. You can also use the F5 / Debug to run the application as well. And now you are aware of the steps that your collaborators will need to take when they download your application.

In Conclusion

Developing with remote containers can be very interesting and keep dependencies on your own operating system out of the picture, and you can virtually ship a development operating system to other developers such that when OS dependencies are discovered they can be added to the development container. These developers can even collaborate regardless of their preferred operating system on their computer.

About Intertech

Intertech is a Software Development Consulting Firm that provides single and multiple turnkey software development teams, available on your schedule and configured to achieve success as defined by your requirements independently or in co-development with your team. Intertech teams combine proven full-stack, DevOps, Agile-experienced lead consultants with Delivery Management, User Experience, Software Development, and QA experts in Business Process Automation (BPA), Microservices, Client- and Server-Side Web Frameworks of multiple technologies, Custom Portal and Dashboard development, Cloud Integration and Migration (Azure and AWS), and so much more. Each Intertech employee leads with the soft skills necessary to explain complex concepts to stakeholders and team members alike and makes your business more efficient, your data more valuable, and your team better. In addition, Intertech is a trusted partner of more than 4000 satisfied customers and has a 99.70% “would recommend” rating.