1 2_getting_started
jason.zhu edited this page 2021-04-22 14:10:48 +10:00

Module 2. Getting Started

Creating a Program with Visual Studio

I prefer vscode + container based development over Visual Studio, hence dotnet cli is utilized. Checking Module 1. Introducing C# and .NET for how to create .NET 5.0 web project.

  • To create empty web app: dotnet new web --name DutchTreat
  • Running web server by: dotnet run <project>, development container will open browser for debugging.

File structure created as shown below

.
├── DutchTreat
│   ├── appsettings.Development.json
│   ├── appsettings.json
│   ├── bin
│   ├── DutchTreat.csproj
│   ├── obj
│   ├── Program.cs
│   ├── Properties
│   │   └── launchSettings.json
│   └── Startup.cs
├── DutchTreat.sln
├── LICENSE
└── README.md

Understanding Program.cs

Default Program.cs is shown as below:

namespace DutchTreat
{
    public class Program
    {
        public static void Main(string[] args)
        // Step 1: When this console web app is started from this entry point
        {
            CreateHostBuilder(args).Build().Run();
            // Step 2: Create a website host given argument, build the host and run it.
            // CreateHostBuilder is defined as shown below
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    // Step 3: For web builder, when start up, use the class called Startup in Startup.cs
                });
    }
}

This structure is rarely changed for .NET Core project.

Understanding Startup.cs

namespace DutchTreat
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                // If get endpoint "/" (i.e. root of website), map to response
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

Where:

  • IApplicationBuilder is an interface defines a class that provides the mechanisms to configure an application's request pipeline.
  • .UseRouting() Adds a Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware middleware to the specified IApplicationBuilder.
  • async context => ... is a async lambda function that directly return page as plain string

Good explanation of IApplicationBuilder and .UseRouting() is available in Deep Dive: How is the ASP.NET Core Middleware Pipeline Built?

By simplify the Configure method, we can get a more primitive configuration in Startup page

       public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }

to

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.Run(async context =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }

Simplified version run app directly, without any routing. Hence even visit http://<web-url>/foo/ will still land in the home page with "Hello World!"

We canalso modify "Hello World!" string to contain html structure

                await context.Response.WriteAsync("<html><body><h1>Hello World!</h1></body><html>");

Serving Your First File

To serve static file in ASP.NET Core:

  1. Put static files into /wwwroot/ directory.
  2. Change Configure method to let Application Builder use StaticFiles.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseStaticFiles();
        }

How to access static page?

ANS: visit http://<web-url:port>/index.html. Static files are served following the directory structure in /wwwroot/

All files are saved in /wwwroot/. Details of wwwroot folder is shown in wwwroot folder in ASP.NET Core

Configure Default Page in ASP.NET Core

Change Startup.cs code to set default page.

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }

Order of command:

  • In void Configure(), we setup order of middleware runs.
    • Middleware = request come in, I want it run it.
    • Order matters in middleware

Explain the middleware order:

  1. app.UseDefaultFiles() search through root directory of /wwwroot for index.html or index.htm or default.html.
  2. app.UseDefaultFiles() then change root URL to the found index.html
  3. request then get parsed to UseStaticFiles()

Hence, change the order will make it unable to present index.html at URL root. Details available in DOTNET Tutorial: Configuring Default Page in ASP.NET Core