Create Your First App Using ASP.NET Core 6 and Visual Studio 2022

This is only introduction about Asp.net Core 6. In this article I will show you how to create your first web application in Visual Studio 2022. I assume that you are already familiar with Visual Studio 2019 and ASP.NET Core in general. This is going to be a quick introduction to give you a feel of the new IDE and project structure.

Getting Started

Please make sure you have installed Visual Studio 2022 and please open your Visual Studio 2022. Create a new project option to reveal the project templates.

Here you can see a list of all available project templates. I have filtered them for C# language and Web project type. As far as ASP.NET Core is concerned the main project templates that you find listed here include:

  • ASP.NET Core Web App (Razor Pages)
  • ASP.NET Core Web App (Model-View-Controller)
  • ASP.NET Core Empty
  • Blazor Server App
  • Blazor WebAssembly App
  • ASP.NET Core Web API (by default uses controller based API but can be changed to Minimal API during project creation)
  • ASP.NET Core gRPC Service
  • Razor Class Library

For this example we will deliberately use ASP.NET Core Empty project template so that we can setup everything on our own rather than relying on the default project items.

So, pick ASP.NET Core Empty and hit the Next button.

Specify some project name (FirstAppInAspNetCore6 in this case) and location and click on the Next button.

In this dialog you can select a .NET version. When you install Visual Studio 2022, .NET 6 is automatically installed for you and hence this dropdown currently has only that entry. The Configure for HTTP checkbox is checked indicating that you want to use Visual Studio’s development SSL certificate while developing the project.

Click on the Create button to finish the project creation wizaed and to create the project as per our specifications. The following figure shows how the Solution Explorer looks like with the Empty project loaded.

Notice that there is no Startup.cs file because VS2022 project templates use the new hosting APIs for the projects. Previously you rarely tampered with Project.cs file. But now Program.cs has a lot more responsibility as you will see shortly.

Double click on the project name in Solution Explorer to open its .csproj file in the editor.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>

As you can see the project’s SDK is Microsoft.NET.Sdk.Web. The target framework is set to net6.0 indicating that we are using .NET 6. Notice the Nullable and ImplicitUsings elements.

The <Nullable> element decides the project wide behavior of Nullable reference types. The value of enable indicates that the Nullable reference types are enable for the project.

The <ImplicitUsings> element can be used to enable or disable what is known as Implicit Usings for the project. When <ImplicitUsings> is set to enable, certain common namespaces are implicitly imported for you. You can read more about this feature here.

You can also take a look at these project settings (and modify them if required) using the project’s properties page. To open the project’s property page right click on the project in Solution Explorer and click on Properties shortcut menu option. The following figure shows a part of this properties page.

You can also search for a particular project setting such as target framework, nullable, or implicit usings this page as shown below:

For this example we won’t change any of these settings. So, let them be at their default values and proceed to the next step.

Now add Models, Views, and Controllers folders as usual. And also add a model class named MyModel to the Models folder.

The default MyModel class contains the following code:

namespace FirstAppInAspNetCore6.Models
{
    public class MyModel
    {
    }
}

Let’s change this code to use file scoped namespaces.

namespace FirstAppInAspNetCore6.Models;

public class MyModel
{
    public string Message { get; set; }
}

As you can see the namespace line now has a semicolon at the end and doesn’t wrap the class inside curly brackets. This indicates that the whole content of the file that follows is part of the FirstAppInAspNetCore6.Models namespace. Thus, MyModel class will be a part of FirstAppInAspNetCore6.Models namespace. Also note that we have added Message string property to the MyModels class.

You will notice that the Message property shows a green underline and displays this warning message:

Open the .csproj file again and change the value of <Nullable> element to disable.

<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>

You will find that the warning disappears. We did this just to check the effect of <Nullable> project settings on the code. Change the <Nullable> setting back to enable.

Let’s also check the effect of <ImplicitUsings> element. Change its value to disable and try building the application.

<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings

You will get this error message in Program.cs file.

Why did this error occur? That’s because the WebApplication class resides in the Microsoft.AspNetCore.Builder namespace. When <ImplicitUsings> was enable, this namespace got automatically imported for us. When we disabled implicit usings, the Microsoft.AspNetCore.Builder namespace was no longer automatically imported for us and the compiler generated the error.

Change <ImplictUsings> back to enable and build the application again. This time the error will disappear and the app will build successfully.

Now add HomeController class to the Controllers folder using Add New Item dialog.

The default HomeController class looks like this:

using Microsoft.AspNetCore.Mvc;

namespace FirstAppInAspNetCore6.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

This code should look familiar to you. We will change this code to the following:

global using Microsoft.AspNetCore.Mvc;

namespace FirstAppInAspNetCore6.Controllers;

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

Notice the code marked in bold letters.

The using statement at the top now has global keyword added to it. This will automatically import the concerned namespace in all the C# classes. For example, if you have three controller classes then you no longer need to use Microsoft.AspNetCore.Mvc in all of them. Just one “global” using will make it available for all C# classes. You can separate all the global using directives in a separate .cs file. For example, you can place the above global using inside a file named GlobalUsings.cs. This way you can manage all the global usings at one place. The following figure shows such a file in a sample project.

The HomeController.cs also uses file scoped namespace – FirstAppInAspNetCore6.Controllers – as discussed earlier.

Now modify the Index() action as shown below:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        MyModel model = new MyModel()
        {
            Message = "Hello World!"
        };
        return View(model);
    }
}

This code is quite straightforward. We simple create an object of MyModel, set its Message property, and pass it to the Index view.

Next, add the Index view using Add New Item dialog.

Write this markup and code in Index.cshtml:

@model FirstAppInAspNetCore6.Models.MyModel

<h1>@Model.Message</h1>

We haven’t added _ViewImports file in the project and hence we need to specify the fully qualified name of the model class in the @model directive.

Before we run the application we need to configure the application’s startup.

Open Program.cs and add the following code to it:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.MapGet("/hello", () => {
    return new List<string>() {
        "Hello World!",
        "Hello Galaxy!",
        "Hello Universe!"
    };
});

app.MapDefaultControllerRoute();

app.Run();

Previously we used two separate files namely Program.cs and Startup.cs to configure app hosting and startup. Now, that task happens in Program.cs itself. The new hosting APIs and new routing APIs along with C# top level statements simplify this process to a large extent.

First, we create a WebApplicationBuilder using the CreateBuilder() method. Then we register MVC specific services with DI container using the AddControllersWithViews() method.

Once a WebApplication instance is built with the help of Build() method we wire a series of middlewares to the HTTP pipeline. This is done using a series of UseXXXXXXX() methods.

Finally, we configure the routing endpoints. The MapGet() method configures a minimal API endpoint at /hello and MapDefaultControllerRoute() takes of the default MVC routing – /controller/action. The MapGet() handler delegate simply returns a List of string messages to the caller. We will invoke this minimal API endpoint from the browser.

The Run() method starts the web application.

Now that our app startup is done, we are ready to run the application. Click on the Start Debugging icon from the Visual Studio toolbar or press F5. You will notice that Visual Studio 2022 uses Kestrel web server by default rather than IIS Express. Of course, you can switch them from the toolbar menu.

Visual Studio 2022 may prompt you about the development SSL certificate. If all goes well you will see “Hello World!” in the browser as shown below:

Notice that the Kestrel web server now uses a randomly generated port numbers instead of fixed 5000 and 5001. You can configure them in launchSettings.json file under Properties folder.

"FirstAppInAspNetCore6": {
    "commandName": "Project",
    "dotnetRunMessages": true,
    "launchBrowser": true,
    "applicationUrl": "https://localhost:7286;
                       http://localhost:5286",
    "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
    }
}

Now, go to the browser’s address bar and navigate to /hello to check whether the minimal API endpoint works as expected. Here is the outcome:

As you can see, we get a JSON array with the three string messages.

Let’s conclude this exploration by checking Hot Reload in action.

Run the application as before so that “Hello World!” is displayed in the browser.

When you run the app, Visual Studio hot reload button menu will be enabled for you like this:

Hot reload allows you to make changes to the HTML, CSS, and C# code and apply them to the app running in the browser, all without stopping and restarting the app.

To test the basic usage of hot reload, go to the Index() action and change the message from “Hello World!” to “Hello Universe!” (don’t stop the app, it should be running in the browser).

public IActionResult Index()
{
    MyModel model = new MyModel()
    {
        Message = "Hello Universe!"
    };
    return View(model);
}

Also open the Index.cshtml and change <h1> to <h3>.

<h3>@Model.Message</h3>

Save both the files, click on the Hot Reload buton (see above figure), and refresh the browser window. You will see the changed message and markup as shown below:

You can further simplify the process of applying the changes by selecting the “Hot Reload on File Save” option. This will perform hot reload as soon as you save the changes (you won’t need to explicitly click on the Hot Reload button).

To summarize, we touched upon several improvements in ASP.NET Core 6 projects and Visual Studio 2022 including <Nullable>, <ImplicitUsings>, global usings, file scoped namespaces, new way of app startup, minimal API, and hot reload.

Happy Coding!

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *