Using .mailmap

When we create a commit in Git we get the author field listing the author’s name and email address. There are occasions where maybe an author is using different email addresses or names and we’d like to “fix” the commits to show the current or correct information for a commit.

Just add a file named .mailmap into the root folder of your project which contains the name of an author along with any email addresses that are to link to that author, for example

Bruce Dickinson  <bruce@im.com> <bruce@samson.net>

See mailmap for more information.

Editorconfig

When we’re collaborating with other developers, whether you’re writing JavaScript, C~ or whatever, it’s useful (some may say essential) to create a coding style that all developers adhere to. After all, one of the aims of collaboration is that you shouldn’t really be able to tell who wrote what code just by the code style.

With web development it’s not unusual to enforce code style etc. with eslint & prettier but this is often shown as a warning when things are working against the style or in some cases, these changes are only applied upon committing the source code. It’s be much better if we could have the editor automatically work the same, for things like indent styles (for example).

This is where the .editorconfig comes in. A file you should commit with your source code and is supported by Visual Code, Visual Studio, JetBrains IDE’s etc.

I’ll be honest, the main reason I use the .editorconfig is to configure my editors to use the same indent_size. Here’s a basic .editorconfig file

root=true

[*]
indent_size = 2
end_of_line = lf

Visual Code has an extension available named EditorConfig which can be used to generate a bare bones .editorconfig for you. Visual Studio has a file template, just add a new file to your project using the Add | New Item… context menu and search for editorconfig. Selecting the editorconfig (.NET) will populate the .editorconfig with lots of options set for various .NET languages.

If you have an .editorconfig file in the root of your project it will be applied to all sub-folders unless overridden by another .editorconfig in one or more of these folders.

If you want to override some, but not all options within the root .editorconfig then just put those additions/changes in the file and ensure

root = true

exists in the root level file.

As you’d expect the .editorconfig is read top to bottom, hence if you have a duplicate key later on in the file this will override any previous value.

References

EditorConfig
Create portable, custom editor settings with EditorConfig

Targeting multiple frameworks in .NET

In this post we’re going to look at the process of targeting multiple .NET frameworks.

You may have seen this concept when installing nuget packages, viewing the package itself and noting that packages have lib folders which (in some cases) have multiple names such as net35, net40 etc. Hence having assemblies which are compatible with those versions of .NET.

For example, the packages/Castle.Core.4.2.1/lib folder contains

  • net35
  • net40
  • net45
  • netstandard1.3

The names are based upon, what’s called, the TargetFrameworkMoniker (or TFM for short), see Target frameworks in SDK-style projects for both a list of TFM’s as well as a Microsoft post of targeting multiple frameworks.

It looks like we need to be using the new SDK csproj files which we can create using either the dotnet CLI or by creating a .NET core or standard projects (or you can use conversion tools).

Let’s therefore walk through the steps for setting up a Class Library that can target a few different frameworks.

  • Create a .NET standard class library
  • Open the csproj file in Visual Studio or your preferred editor
  • Change the following
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
      </PropertyGroup>
    
    </Project>
    

    to use TargetFrameworks (plural) and add any frameworks you’re targeting delimited by a semi-colon, i.e.

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
      </PropertyGroup>
    
    </Project>
    
  • Save and if necessary reload Visual Studio to see the effects of these changes.

If all went well you should see The Dependencies section of your project (within Visual Studio) lists both

  • .NETFramework 4.5
  • .NETStandard 2.0

If you now build your project you’ll get both net45 and netstandard2.0 folders/builds in the bin/Debug and bin/Release folders.

We can now either explicitly add assemblies or packages to our framework specific dependencies and ofcourse, by using preprocessor symbols such as NETSTANDARD2_0 and NETFRAMEWORK or NET45 we can begin to conditionally compiler code for the different target frameworks.

We can add nuget to install package and add references to our multiple targets, but in some circumstances we might need to be more specific about which package is referenced by which target.

In such cases we can add the reference to the application using Visual Studio and then edit the csproj ourselves to add a Condition around the reference, for example

<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
  <PackageReference Include="Microsoft.Net.Http" Version="2.2.29" />
</ItemGroup>

In this example, only the .NET 3.4 target will get the reference added to it.

Now we’ve seen how to add conditions to our csproj we can also define constants for use also (or ofcourse using the project properties tab within Visual Studio to add these), for example

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
   <DefineConstants>SOME_CONSTANT</DefineConstants>
</PropertyGroup>

References

Target frameworks in SDK-style projects
Support multiple .NET versions
.NET Standard

ASP.NET Core and Web API

In the past I’ve looked at ServiceStack for developing REST services however there are alternatives to ServiceStack, one of which is Web Api. Let’s create a simple starter project using ASP.NET Core and Web Api to implement our services.

  • Create a new ASP.NET Core Web Application
  • Select API

The generated service supplies a Controllers/ValuesController.cs file which includes a controller class with the various REST methods.

Controllers partition your application’s API, so for example you might have an AuthenticateController solely for authentication methods and another controller for CRUD operations on a datasource.

For example this is a simple AuthenticateController class

[Route("[controller]")]
[ApiController]
public class AuthenticateController : ControllerBase
{
   [HttpPost]
   public ActionResult<AuthenticateReponse> Post([FromBody] User user)
   {
      return new AuthenticateReponse
      {
         Token = $"{user.Name}|1234"
      };
   }
}

Here, the Route is set to [controller] so our URL would be http://localhost/Authenticate. In this example we intend for the user to send data within an HTTP POST method, passing a User object (which is a simple name/password object). An AuthenticateResponse object is return via the ActionResult.

The ActionResult return value allows us to return HTTP 200 OK or using subclasses such as BadRequest for an HTTP 400 and there are other derivations for other HTTP responses.

The Action<> allows us to return a 200 OK without the need of using the Ok() method, although this can be used if preferred.

When using different return responses it’s good to also document these by adding

[ProducesResponseType(400)]

This indicates that the method may return an HTTP 400. This is useful for use with Open API tools such as Swagger.

As can be seen in the Post method, the User object is expected within the method’s body and the HttpPost attribute declare the method uses HTTP POST, the method name is superfluous in terms of the REST API.

The different HTTP methods

The code generated by the template creates a ValuesController with various HTTP methods, which I’ll recreate here for reference

HTTP GET without URL parameters

[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
   return new string[] { "value1", "value2" };
}

HTTP GET with URL parameters

[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
   return "value";
}

HTTP POST without URL parameters

[HttpPost]
public void Post([FromBody] string value)
{
}

HTTP PUT with URL parameters

[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}

HTTP DELETE with URL parameters

[HttpDelete("{id}")]
public void Delete(int id)
{
}

HTTP HEAD

[HttpGet, HttpHead]
public IActionResult Head()
{
   return Ok();
}

We would request the headers using HttpHead along with an HttpGet.

HTTP PATCH

[HttpPatch]
public IActionResult Patch()
{
   return Ok();
}

Adding Swagger support

As per ASP.NET Core Web API help pages with Swagger / OpenAPI we can add Swagger support using either Swashbuckle.AspNetCore or NSwag (there may be others). Both are simple to add to our project.

Logging in Blazor

It’s not unusual for us to need to output log message to file, console etc. Obviously there’s going to be a different in capabilities for logging from WASM (essentially on the client browser) and on a server.

Blazor supplies the logging framework

Blazor supplies loggin via the ILogger, ILogger, ILoggerFactory and ILoggerProvider interfaces. In most cases you’ll use the ILogger and ILogger.

Logging capabilities are supplied via the WebAssemblyHostBuilder on WebAssembly and Host on the server (see Program.cs in both project types).

We can therefore use these interfaces/implementation via injection like this

@inject ILogger Logger;
// OR
@inject ILogger<MyPage> Logger;

Alternatively we might use the ILogFactory like this

@inject ILoggerFactory LoggerFactory

// with the following
var logger = LoggerFactory.CreateLogger<MyPage>();

Logging in WebAssembly

With WebAssembly on the client, we’d obviously expect to be logging to the Browser devtools. Whilst we can actually just use

Console.WriteLine("Message 1");
Debug.WriteLine("Message 2");

the Logging framework offers some extra functionality, such as categorisation of logs etc. To use the ILogger or ILogger, we simply use

Logger.LogWarning("Log a warning");

(we have the ability to log debug, warning, info etc.)

Logging to Server

For Blazor Server, the output from the logging will be visible in the console window if running as a standalone application or the output window of Visual Studio.

However if you want your Blazor server application to output to the browser, then you need to use the IJSRuntime, which we can inject like this

@inject IJSRuntime JsRuntime

and then use the runtime like this

JsRuntime.InvokeAsync<string>("console.log", "Browser Message");

as you can see, the runtime allows us access to the JavaScript runtime hosting our pages and we can call the console.log JavaScript method, passing the parameters for the method call. In our case it’s just a string “Browser Message”.

Adding custom logger

To add a custom logger we can use something like this, where the DebugProvider is our implementation of an ILoggingProvider

builder.Logging.AddProvider(new DebugProvider());

Configuration

Configuration is placed in the appsettings.json file (remember if you’re using appsettings.json on WebAssembly client then this should be placed in the wwwroot folder otherwise it’s not set to the browser). For server the appsettings.json can be in the project folder.

Here’s the template generated appsettings section for logging

"Logging": {
  "LogLevel": {
    "Default": "Trace",
    "Microsoft": "Warning",
    "Microsoft.Hosting.Lifetime": "Information"
  }
},

Creating Blazor fragments

At some point you may need to dynamically create elements of mark-up in a Blazor application. For example, you might create a reusable class library for returning components, icons or the likes depending upon the user.

Ofcourse we can do this from the @code block within a page or we might prefer to simply return mark-up from a function.

Let’s look at a simple example method which, depending upon the id sent to it returns a different icon, here’s an abridge snippet of the code

public static RenderFragment GetIconForId(int id)
{
   var iconType = typeof(ListIcon);
   switch (id)
   {
      case 0:
         iconType = typeof(HomeIcon);
         break;
      case 1:
         iconType = typeof(NotificationImportantIcon);
         break;
      // etc.
   }
   
   return builder =>
   {
      builder.OpenComponent(0, iconType);
      builder.CloseComponent();
   };
}

As you can see we return a RenderFragment which is actually just a delegate which takes a RenderTreeBuilder argument. From this builder we create/append a child component, the first value is a sequence (a position of the instructions in the source code) followed by the type of the child component to add.

If the case above, the HomeIcon is an Icon from Skclusive.Material, which is ultimately an Microsoft.AspNetCore.Components.IComponent.

So anything that takes a RenderFragment will now display the icon that’s returned via the method in our example.

We can also use AddAttribute to our component, see RenderTreeBuilder for more information.

Basically it’s not dissimilar (as you’ve expect) to create XML documents using the XmlDocument classes etc.

Blazor routing and Navigation

Routing

If you take a look at the generated pages for a Blazor application, you’ll see the following

@page "/counter"

this denotes a route to our page, i.e. http://localhost:44319/counter.

Note: When you compile your application a file is generated (see Counter.g.cs in compiled folder) and this page declaration is converted to a RouteAttribute.

You can have multiple routes pointing to the same page, in this example all these routes will navigate to the same Counter.razor page

@page "/counter"
@page "/mycounter"
@page "/something"

Probably more useful is the ability to add parameters to our routes, for example

@page "/counter"
@page "/counter/{InitialValue}"

By default InitialValue is of type string, but we can change this by using a constraint, for example

@page "/counter"
@page "/counter/{InitialValue:int}"

Now we simply create a property in our code with the ParameterAttribute applied to it, like this

[Parameter]
public int? InitialValue { get; set; }

We use a nullable int in case the value is missing. We can also have routes handling different type contraints (for example a string or on int) to mean two different things

@page "/counter"
@page "/counter/{InitialValue:int}"
@page "/counter/{SomeString}"

In our OnInitialized() method (part of the component life cycle) we might then set the currentCount to InitialValue.

The routes are declared in our pages but the routing component itself can be found in App.razor. In this case the Router will locate the routes from the supplied AppAssembly

<Router AppAssembly="@typeof(Program).Assembly">

We can also includes routes within AdditionalAssemblies, for example maybe you’ve got some reusable components with routing supplied, hence we write

<Router AppAssembly="@typeof(Program).Assembly" 
   AdditionalAssemblies="new[] { typeof(MyComponents).Assembly }>

Navigation

If you want to navigate to other pages, we need to use the NavigationManager. This needs to be injected into our page, using

@inject NavigationManager NavManager

Now to navigate, for example when a button is click, we use the following

NavManager.NavigateTo("counter/2");

In the instance we’ll navigate to the relative URL/page with “counter/someData”.

This works fine when navigating to other pages but if we want to navigate within a page and we’re using the component’s OnInitialized method to initialize data?

Because OnInitialized is called when the page is initial loaded and because we’re already in the page, this method will not normally be called again if we navigate within the page, so we simply need to supply an extra parameter to our NavigateTo code to force the page to reload, i.e.

NavManager.NavigateTo("counter/2", true);

Note: An alternative solution ofcourse is to override the other life cycle method OnParameterSet and instead move initialization code to that method.

Visual Code debugging in Chrome

I’m using Visual Code for my React development and I’m using Chrome as my browser – I want to debug my React code in Chrome using Visual Code, so let’ see how it’s done.

First off, check out Introducing Chrome Debugging for VS Code, secondly VS Code – Debugger for Chrome.

Or, if you prefer, here’s the steps

  • Ctrl+Shift+X within Visual Code to load the Extensions list
  • Search for Debugger for Chrome and install it (if not already installed)

You’re going to need a launch.json file in the .vscode folder, here’s a minimal example

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome",
            "url": "http://localhost:3000",
            "webRoot": "${workspaceFolder}"
        },
        {
            "type": "chrome",
            "request": "attach",
            "name": "Attach to Chrome",
            "port": 9222,
            "webRoot": "${workspaceFolder}"
        }
   ]
}

In the above we have two configurations, both for Chrome, one launches Chrome with the supplied URL, the second attaches to an existing instance of Chrome.

If you now choose the option Run | Start Debugging, Chrome will launch with your URL loaded. You can place breakpoints in your code (before or after you start debugging) and you’re application will break at these breakpoints as you’d expect and you can inspect variables etc. So basically a full debugging experience.

Default commands within debug mode are as follows

  • F5 Continue
  • F10 Step Over
  • F11 Step Into
  • Shift+F11 Step Out
  • Ctrl+Shift+F5 Restart
  • Shift+F5 Stop

To attach to an existing running instance of Chrome, ensure you start Chrome with the following command line parameters –remote-debugging-port=9222, for example create a shortcut link with Target “C:\Program Files\Google\Chrome\Application\chrome.exe” –remote-debugging-port=9222.

You’ll also need to ensure only this instance of Chrome is open/running and then you can run the “Attach to Chrome” option.

Adding imports to your Blazor app.

The default template’s supplied for Blazor Server and WebAssembly applications, gives you lots upfront. However, ofcourse you’re likely to want to import further functionality via the @using directive.

For example, let’s say we want to add the following to the Counter.razor IncrementCount method (from the default template generated files)

Debug.WriteLine("Increment");

We can simply add the following to the top of the Counter.razor file

@using System.Diagnostics

Alternatively and especially useful for using code across multiple pages/components, you can put the above code into the _Imports.razor file. Think of this as a global set of using reference, but only for @code sections, for standard C# classes we ofcourse use the using directive as usual.

Note: I’ve found my current version of Visual Studio doesn’t seem to immediately recognise the updated _Imports.razor file, a build fixes that.

Getting started with Blazor on Server and WebAssembly

As of Visual Studio 16.6.3 and .NET core 3.1.301 there’s now support for create Blazor applications for Server and WebAssembly.

Creating your project

From Visual Studio

  • Create a new project and look for the Blazor App template
  • You’ll be presented with the options to create a Blazor Server App or Blazor WebAssembly App

From the dotnet CLI

  • To create a server app run
    dotnet new blazorserver -o your-app-name
    
  • To create a WebAssembly app run
    dotnet new blazorwasm -o your-app-name
    

You can also run the generated code by changing directory to the your-app-name and then execute the following

dotnet run

Whichever route you took to generate your Blazor app. When you run the application, you can access the application via https://localhost:5001/.

Blazor Server

I’m not going to cover Blazor on the server specifically, as this is very much like Blazor WebAssembly crossed with ASP.NET core development. Basically what you write for WebAssembly is very much the same as you’d write for the Server.

There are benefits and downsides to Blazor Server and Blazor WebAssembly, I’m not going to list them all (because I’m sure I’ll forget one or two) but basically running Blazor on the server gives faster start-ups, allows us to be more secure with our source code (in that the code is not available to be downloaded but runs instead on the server). However the Server implementation suffers from the lack of an offline mode (i.e. PWA is supported via Visual Studio for Blazor WebAssembly) and there’s bound to be more network traffic with a server implementation.

Blazor WebAssembly

WebAssembly or WASM is a binary instruction set for browsers (well those that support it). Think of it as a virtual machine for running byte code. The important parts of WASM are that any it can run code generated from C# (other languages are adding support) instead of just using JavaScript for the Web. The second thing of interest is that the virtual machines are sandboxed.

It might sound like we’ve sort of been here before, and we have to a degree, but this time we have an open standard instead of plugins, Java applets, Silverlight or ActiveX.

With Blazor WebAssembly the compiled code is executed on the client, within the browser as a SPA. With Blazor Server, much like ASP.NET, the code comes from the server, however clever use of SignalR allows diffs to/from the DOM to be sent back and forth in an efficient manner.

Looking into the Blazor templates

If we look at both the WASM and Server code we’ll see our pages written in Razor syntax, here’s the Counter.razor file

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Razor syntax is denoted by the @ prefixed commands, for example @page is basically a routing command to this counter page. @code is a C# code block. Also we can use variables from our code by prefixing with the @ (such as @currentCount).

When you see a @code block, think of it as a class, hence in this example we have a field currentCount and a member method named IncrementCount.

Binding

One way binding is very simple (and shown in the above snippet)

<p>Current count: @currentCount</p>

In this case the variable is updated via the @code and one way binding ensures that the text in the HTML is updated automatically for us.

Ofcourse we’re going to need two-way binding and this is pretty simple in Blazor. Let’s add an input to the Counter.razor code (just place above the button HTML).

<input @bind="currentCount" />

This input will by default, bind the variable currentCount to it’s value property, we can also write explicit code for this in this way

<input @bind-value="currentCount" />

You use the syntax @bind-{Property} replacing {Property} with whatever the property or attribute name is that you wish to bind to.

What happens now is that, when the user changes the input value and the control loses focus, the currentCount is automatically set to the new value. We may want to instead have the value update as the input changes, in this instead we use @bind-value:event, for example

<input @bind-value="currentCount" @bind-value:event="oninput"/>

Note: if you put a char or string into the input, the binding doesn’t update and hence you get no exceptions or anything.

Blazor Components

Each page that we have is basically a Blazor component, but we can create a component that’s not a page – in other words it’s just a component and will be used to render HTML fragments.

From Visual Studio, right mouse click on the Shared folder and then select Add | Razor Component. Mine’s named Count.razor and the aim is to move the code into it’s own component

<p>Current count: @currentCount</p>

I called my component Count.razor. Let’s change the Counter.razor page to use this new component, so replace the code and above with

<Count @bind-Counter="currentCount"></Count>

Here’s our Count.razor component code

<p>Current count: @Counter</p>

@code {
    [Parameter]
    public int Counter { get; set; }

    [Parameter]
    public EventCallback<int> CounterChanged { get; set; }
}

Whilst we’re not using the CounterChanged event, it’s required for the binding code. The ParameterAttribute is basically exposing properties to the parent components or pages, i.e. for use outside of the component itself.

Now I’m not 100% on this code (i.e. CounterChanged not being used) as it worked fine, but I was finding Visual Studio displays error tildes under the currentCount usage in the Counter page, although everything worked. I’m not sure if this is just an issue where Visual Studio it not yet upto date with all the syntax or a mistake on my part – although it does work.

However, if we just change the page’s code to

<Count @bind-Counter="currentCount" 
   @bind-Counter:event="CounterChanged"></Count>

then no error tildes were displayed in Visual Studio – this needs further investigation as it seems a bit superfluous adding this event when it’s not used – but hey, I’m new to Blazor!

That’s it for Getting Started.

References

Razor syntax reference for ASP.NET Core
WebAssembly
Introduction to ASP.NET Core Blazor