Category: .Net Core

Default ctor injected private member names with underscore prefix in Visual Studio 2019

After a bit of experimentation, you might want to change the default member generation when you add an injected member to your C# constructor in Visual Studio 2019.

Here’s what you likely want to use as a private member in your class:

private readonly IHttpContextAccessor _httpContextAccessor;

Here’s what the constructor (ctor) looks like:

public BearerTokenHandler(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor ??
throw new ArgumentNullException(nameof(httpContextAccessor));
}

To get that automatically, you’ll need to change the option for it which is deep inside the Visual Studio options menu.

First, navigate to:

Tools->Options->TextEditor->C#->CodeStyle->Naming

Click on the “Manage naming styles” button.

manage1

Fill it out like this:

manage2

Close that and then choose your new specification naming style for “Private or Internal Field”:

manage3

Click “OK” and it should immediately take effect next time you use the “Quick Refactorings” wizard to add a new member.  Try it out!

.NET Core Middleware bridge for NPM

The late, great .Net guru K Scott Allen created and supported a middleware bridge for .Net Core projects that provide support for using NPM modules (“package.json”) in .Net projects.   This NuGet library will install the support for you.

What it will get you is the ability to reference external libraries such as jQuery and bootstrap within a web project in .Net Core.

Usage is quite simple.  Simply pull the package down via NuGet, install your npm packages and then add this simple line in startup.cs:

app.UseNodeModules();

That’s it.   Then in your source html and razor pages you can reference the /node_modules directory as if it was a child of the wwwroot folder which is where .Net core normally looks for static files.

Hosting a .NET Core 3.1 MVC web on Amazon Elastic Compute Cloud (EC2)

I undertook an adventure starting this past weekend to get some experience with Amazon Web Services (AWS).   I started by taking several beginner courses on Pluralsight.  This course, AWS Developer: Getting Started by Ryan Lewis, is wonderfully detailed and walks you through setting up an EC2 instance, adding security groups, granting access to ports and other important base concepts.   But he was using a NodeJs app as an example app to host on AWS.   I wanted to learn how to host a .NET Core app instead.

I built a little example app which was helping me to study for an Amazon interview that served up random interview questions or one of Amazon’s Leadership Principles.  Great.  Now how do you go about hosting a .NET Core app on EC2?

The EC2 instance I chose was the Amazon Linux 2 operating system.   Note that this closely (read “is the same as”) mirrors the Centos 7 flavor of Linux which supports .NET Core.   I found some invaluable “how to” videos on YouTube by Jon Jensen.  They were a little dated since they came from 2018 and targeted an older version of .NET Core, Amazon Linux, etc.

The first thing you do after updating the Amazon Linux 2 OS with the latest patches was to install .NET Core on the EC2 instance.   This document on Microsoft’s site was excellent and I didn’t have any issues.

Next up was packaging the .NET code.  You compile a .NET Core app with the following command line:

$ dotnet publish -o awssite

This creates a directory called “awssite” (you can name it anything) and packages all the dependencies.   How do you get your code to the EC2 instance?  I’m sure there are several ways, but I chose an SSH utility.  What is wonderful is that Microsoft has now included SSH tools in Windows as a native optional feature.   Now you can follow along with tutorials that use Unix style command line examples.  This command copied my compiled output to a folder on the instance:

C:\dox\code\git\AmazonInterviewQuiz\awssite>scp -r -i c:\dox\code\AWS\[YOUR_SSH_KEY_FILE].pem c:\dox\code\git\amazoninterviewquiz\awssite\ ec2-user@[YOUR_EC2_EXTERNAL_IP]:/home/ec2-user/[DIRECTORY_FOR_COMPILED_CODE]

Great so far!

After your code is staged on the EC2 instance, you have to have some way to map inbound HTTP requests to your .NET Core app.   .NET Core apps use Kestrel self-hosting and you must configure a reverse proxy on Linux to forward the request to Kestrel. Again, Microsoft has a very nice document for how to do this.

Here’s where we have a Google/StackOverflow moment.   I had to make changes to the configuration file.  My “awssite.conf” file is as follows after some trial and error (namely the log file and removal of a superfluous entry):

[ec2-user@ip-10-0-1-72 conf.d]$ more awssite.conf

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5000/
    ProxyPassReverse / http://127.0.0.1:5000/
    ErrorLog /var/log/httpd/awssite-error.log
    CustomLog /var/log/httpd/awssite-access.log common
</VirtualHost>

You can see the differences if you look at the example in the Microsoft web page for Apache install.

Okay, now for an ad hoc test of the app!  You start a .NET Core app with the following simple syntax (again all of this is via SSH):

[ec2-user@ip-10-0-1-72 awssite]$ dotnet AmazonInterviewQuiz.dll
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/ec2-user/timeline/awssite

After testing the config and bouncing the Apache process, I then tried to issue a curl request to test the localhost functionality.   I got zero bytes.   Looking at the output closely, I noticed TWO ports were listening?  Why was https listening on 5001?  Anyways, I got an empty curl response which wasn’t good but didn’t tell me anything more.

I opened the awssite-error.log and the awssite-access.log and found nothing suspicious. I fired up a browser on my local Windows PC and received an HTTP 502 error.  Hmmm.  I fired up trusty Fiddler and discovered the initial request was immediately redirected from the 5000 port to the 5001 port.  What is going on?

After some StackOverflow deep dives, here’s the “problem”.  Microsoft introduced a “feature” in the recent releases of .NET Core to try to redirect always from http to https if the initial request was http.   I was ignorant of that.   This post on StackOverflow and this other one gave me the direction I needed to take.

I made two changes to my source code.  First, I removed this line from the boilerplate scaffolding code in Startup.cs:

app.UseHttpsRedirection();

Secondly, I manually configured the webserver in Program.cs:

public static IHostBuilder CreateHostBuilder(string[] args) =>
     Host.CreateDefaultBuilder(args)
         .ConfigureWebHostDefaults(webBuilder =>
         {
             webBuilder.UseKestrel(options =>
             {
                 options.Listen(IPAddress.Loopback, 5000);
             });
             webBuilder.UseIIS();
             webBuilder.UseStartup<Startup>();
         });

Here, you see I have OMITTED the default of 5001 which effectively disables https support for the app.   This is OF COURSE not recommended for production apps.

After that was tested locally I had to republish the code to the EC2 instance and restart my app.   Everything now works perfectly.

.Net Core Source

Microsoft open sourced its code a few years ago and it is extremely interesting to dig into it to get deeper meaning on some fundamentals of, for example, how MVC’s pipeline handles a request and creates a response.

I went through this fantastic Pluralsight course on ASP.NET Core 3.0: The MVC Request Life Cycle by Alex Wolf, which pointed me to the .Net Core Repository  Setting break points and stepping through the source code shows how the framework selects controller actions and intercepts and modifies the request through middleware and action filters.   This was something I knew about at a high level but now I feel enlightened and more confident in using the technology.

I’m enjoying this time I have to study – next up is dipping my toes into the React pool (ocean?).