Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 2

Angular2, ASP.NET Core, Visual Studio Code, Part 2

Derived from photo by Markus Spiske / raumrot.com, CC-BY

This is part two in a series of posts teaching you how to create your first Angular 2 application with ASP.NET Core in Visual Studio Code. Here is the list of posts:

In this post, you setup a basic ASP.NET Core application to serve static files using the terminal in Visual Studio Code. To ensure you have the proper dependencies installed, please see the first post.

.NET Core SDK Preview 3: This tutorial uses .NET Core SDK Preview 3 which is available on GitHub. This version includes 'alpha' support for MSBuild-based projects that use .csproj configuration instead of project.json configuration. Microsoft announced that MSBuild is the common project configuration for .NET Core based projects going forward. By using MSBuild, the goal is to better prepare you for future versions of the tooling.

If you would like to jump straight to the code, it's all on GitHub.

The .NET Core CLI

The .NET Core command-line interface (CLI) is the base, cross-platform level of tooling provided with the .NET Core framework. The recommendation is that all other tooling is built off of this base making it an attractive place to start learning the framework.

First create a directory in which you will build this application using whichever tool you prefer (command/terminal window, file explorer). Then open Visual Studio Code. Now from the File menu, select Open Folder… to open the target directory.

open folder

Note: there are several ways to open a specific directory in Visual Studio Code. First if already in a command/terminal window, use the command code . to open up the current directory in Visual Studio Code. Also if in Windows File Explorer, right-click on a directory to open in Visual Studio Code.

You now have your application directory setup in Visual Studio Code. Press Ctrl + ` to open Visual Studio Code's terminal.

Next, type the command dotnet new in the terminal pane. This command creates two files in your application directory: a .csproj named after the current folder and Program.cs. The .csproj contains the information needed by the build to create your application. The Program.cs file contains the code that executes when the application runs.

Note: you may have seen a .xproj file extension paired with a project.json file in previous versions of ASP.NET Core. Going forward, the standard is to use .csproj or the equivalent file extension for your chosen language.

Before running the application, you must download the required dependencies. In the terminal, type dotnet restore. This command downloads packages from Nuget required to build and run your .NET-based application.

Once the dotnet restore command is complete, type dotnet run to build and run the code. You should see "Hello World!" displayed in the terminal. Congratulations, you built your first .NET Core application!

Now the objective is to move "Hello World!" from the terminal to the browser.

Initialize the Web Host and Kestrel

In ASP.NET Core, the web host bootstraps and manages a server. The server handles the HTTP requests and responses. So you need a host in order to have a server.

First, modify your .csproj file with the required dependencies. It should look like this:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp1.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <Compile Include="**\*.cs" />
        <EmbeddedResource Include="**\*.resx" />
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.NETCore.App">
        <Version>1.1.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.NET.Sdk.Web">
        <Version>1.0.0-alpha-20161104-2-112</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AspNetCore.Hosting">
        <Version>1.1.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel">
        <Version>1.1.0</Version>
        </PackageReference>
    </ItemGroup>

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Then run dotnet restore from the terminal to download the newly added packages.

The web host and web server are configured together using a series of extension methods. For this example, you are using Kestrel, a light-weight and cross-platform server designed for ASP.NET Core. The application's entry point is the static void Main method found in Program.cs. Replace the code in Program.cs with the following to configure the web host and web server:

using System.IO;
using Microsoft.AspNetCore.Hosting;

class Program
{
    static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseWebRoot(Directory.GetCurrentDirectory())
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

The new WebHostBuilder() constructor returns an IWebHostBuilder instance which is then configured using extension methods. The UseKestrel() extension method configures the host to use the Kestrel web server.

Create one more file in your application directory named Startup.cs, with a class named Startup. When creating a web host, you must provide a class containing startup configuration information. The startup class must contain a public void Configure() method to complete the configuration contract. You will come back to this file, later. For now, the code should look like this:

public class Startup
{
    public void Configure() { }
}

The UseContentRoot() method configures ASP.NET Core to use the specified directory when looking for static files during ASP.NET operations. The method Directory.GetCurrentDirectory() gets the path of the current working directory which for this example is the directory in which Program.cs resides.

Note: with this version of the SDK, you may see some of your code decorated with green underlines saying something about mimatched versions of System.Runtime. The SDK tooling is still in preview and this should not prevent you from completing the steps.

The UseWebRoot() method deserves some explanation. the web root is different than the previously configured content root. Think of content root as being a base path for the ASP.NET framework versus web root being the base path for the web server. Most of the templates for ASP.NET Core use the default web root which is a directory named wwwroot. However, a lot of the getting started Angular and front-end examples out there use the working directory as the web root not to mention that this behavior mirrors the original ASP.NET behavior. Use the working directory as a simple configuration while getting started.

Note: At some point when you begin to pre-compile and bundle your Angular application, having a separate web root such as wwwroot makes sense to separate your source code from your deployable assets so it's important to note this configuration option.

Finally, the Build() method packages this extension-method-based configuration into an IWebHost instance which is then started by calling its Run() method. Now in the terminal (Ctrl + `), type dotnet run and your application compiles and runs on http://localhost:5000 by default. At this point, just confirm the project starts in the terminal. There is nothing more to see yet. Shut down the application by placing focus in the terminal and typing Ctrl+C.

Note: As with the original Visual Studio, the F12 key takes you to the defintion of an API.

Configure Static File Support

In order to actually serve an HTML file to the client, you must enable static file support in ASP.NET Core. You need to download a new Nuget package and configure with the Startup class.

First, go to your .csproj file and add the following reference:

<PackageReference Include="Microsoft.AspNetCore.StaticFiles">
  <Version>1.1.0</Version>
</PackageReference>

Once you have added the reference, restore the package with dotnet restore in the terminal.

Once restored, go to the Startup.cs file. Similar to configuring the web host, you configure the ASP.NET application using extension methods. The new configuration looks like this:

using Microsoft.AspNetCore.Builder;    

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseDefaultFiles();
        app.UseStaticFiles();
    }
}

Save your files and continue to the next section.

Hello, World!

Now, add an index.html file to your application directory with the contents Hello, World!. In the terminal, type dotnet run and then visit http://localhost:5000 in your browser. You should see Hello, World! displayed. Congratulations, you built a basic ASP.NET Core application from scratch!

Hello, World!

Conclusion

If you are an experienced ASP.NET developer in Visual Studio, you might be thinking how much you took for granted with the framework and tooling in the past. This setup is significantly different than File, New Project in Visual Studio so please refer to the code on GitHub.

Now you understand the basic mechanics of starting an ASP.NET Core application. You setup a web host, web server, and static file support. You know the difference between content root and web root. With this scaffolding, it's time to start building the Angular 2 piece in the next post.

11 thoughts on “Your First Angular 2, ASP.NET Core Project in Visual Studio Code – Part 2”

    1. Yes, it’s important to know that is there. I looked at the built-in template for ASP.NET and thought it might not be the best for Angular 2 development. So the approach here is to start from almost nothing and then build in what we need versus using the default template and have to remove stuff we don’t need. But yes, it’s good to know that there is a template in the box for web development. As far as I know they are working on but haven’t released custom templates – that’s really what I want 🙂

      Thanks for the comment!

  1. I am running .NET Core and Visual Studio Code on the Mac and am able to pass all steps from this tutorial so far (at this moment I finished step 3). Instead of a .csproj file my dotnet template still included a project.json but was able to work around this. I used yeoman to include an Empty web template for the .NET Core back-end and stripped it down a bit. All NPM set-up worked out of the box as described.

    1. Hi Erik,
      I’m using a Mac as well and also don’t have a .csproj. Can you elaborate on your workaround using yeoman? I have not used this utility. What is the equivalent of updating the .csproj step since I don’t have one?

  2. Maybe I did something wrong, but I came up with the following error:
    The specified framework ‘Microsoft.NETCore.App’, version ‘1.1.0’ was not found.

    So I modified this line:

    1.0.0
    To Version 1.0.0
    After that I used saved the file, ran ‘dotnet restore’ then ‘dotnet run’ and I successfully started the server.
    ‘Now listening on: http://localhost:5000

    1. Looks like encapsulating text in brackets does not show. Referring above, but with brackets:
      PackageReference Include=”Microsoft.NETCore.App”
      Version1.1.0/Version
      Changed to ‘1.0.0’

      1. Hi Aaron, I’m curious which dotnet version is installed? This is the dotnet CLI version I’m talking about. If you type `dotnet –version` in the terminal it will show you. This tutorial uses 1.0.0-preview3-004056. There’s still a bit of churn in the tooling so the dotnet CLI version could make a difference. But if there is something in the post I need to update, I’d like to know. Thanks

  3. Hi Aaron,
    I found that running dotnet new from the terminal within VS Code generated a project.json and Program.cs (no .csproj file generated). I wonder if this is related to the version of VS Code I am using (1.8.1).

    Regardless, I was able to complete this part of the tutorial successfully by adding the same required dependencies to my project.json file. I have pasted the contents of my project.json file in case others run into a similar experience and need some help:

    {
    “version”: “1.0.0-*”,
    “buildOptions”: {
    “debugType”: “portable”,
    “emitEntryPoint”: true
    },
    “dependencies”: {},
    “frameworks”: {
    “netcoreapp1.1”: {
    “dependencies”: {
    “Microsoft.NETCore.App”: {
    “type”: “platform”,
    “version”: “1.1.0”
    },
    “Microsoft.NET.Sdk.Web”: {
    “type”: “default”,
    “version”: “1.0.0-alpha-20161104-2-112”
    },
    “Microsoft.AspNetCore.Hosting”: {
    “type”: “default”,
    “version”: “1.1.0”
    },
    “Microsoft.AspNetCore.Server.Kestrel”: {
    “type”: “default”,
    “version”: “1.1.0”
    },
    “Microsoft.AspNetCore.StaticFiles”: {
    “type”: “default”,
    “version”: “1.1.0”
    }
    },
    “imports”: “dnxcore50”
    }
    }
    }

    Looking forward to next parts!

  4. Could you tell me the difference between your

    and the

    auto-generated by the VSCode?

    I’m currently having troubles with publishing your angular2-aspnetcore-starter project, could you guide me, please?

Leave a Reply

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