Cross site access in IIS

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

How do we handle CORS (cross site) access within IIS, i.e. how to we allow/enable it?

We simply need to create a web.config file in the root of our web application, here’s an example

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <defaultDocument>
      <files>
        <clear />
        <add value="data.json" />
      </files>
    </defaultDocument>
    <staticContent>
      <mimeMap fileExtension=".json" mimeType="text/json" />
    </staticContent>
    <httpProtocol>
      <customHeaders>
       	<add name="Access-Control-Allow-Origin" value="http://localhost:3000" />
      	<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" />
      	<add name="Access-Control-Allow-Credentials" value="true"/>
      	<add name="Access-Control-Allow-Headers" value="X-Requested-With, origin, content-type, accept" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

Here, within the customHeaders section we explicitly allow origin of localhost (this value could be set to *).

C# 8.0 nullable and non-nullable reference types

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

One of the key C# 8.0 features is nullable/non-nullable reference types, but before we get started you’ll need to enable the language features by editing the csproj and adding the following to each PropertyGroup

<PropertyGroup>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
</PropertyGroup>

You can also enable/disable on a per file basis using

#nullable enable

and to disable

#nullable disable

What’s it all about?

So we’ve always been able to assign a null to a reference type (which is also the default value when not initialized), but ofcourse this means if we try to call a method on a null reference we’ll get the good old NullReferenceException. So for example the following (without #nullable enable) will compile quite happily without warnings (although you will see warnings in the Debug output)

string s = null;
var l = s.Length;

Now if we add #nullable enable we’ll get the warnings about that we’re attempting to assign a null to a non-nullable. Just like using the ? as a nullable for primitives, for example int? we now mark our reference types with the ?, hence the code now looks like this

string? s = null;
var l = s.Length;

In other words we’re saying we expect that the string might be a null. The use of the non-nullable on reference types will hopefully highlight possible issues that may result in NullReferenceExceptions, but as they’re currently warnings you’ll probably want to enable Warnings as Errors.

This is an opt-in feature for obvious reasons i.e. it can have a major impact upon existing projects.

Obviously you still need to handle possible null values. Partly because you might be working with libraries which do not have this nullable reference type option enabled, but also because we can “trick” the compiler – so we know the previously listed code will result in a Dereference of a possibly null reference warning, but what if we change things to the following

public static string GetValue(string s)
{
   return s;
}

// original code changed to
string s = GetValue(null);
var l = s.Length;

This still gives us a warning Cannot convert null literal to non-nullable reference type so that’s good but we can change GetValue to this

public static string GetValue([AllowNull] string s)
{
   return s;
}

and now, no warnings exist – the point being that even with nullable reference types enabled and not marking a reference type as nullable, we can still get null reference exceptions.

Attributes

As you’ve seen, there’s also (available in .NET core 3.0) some attributes that we can apply to our code to the compiler a little more information about our null expectations. You’ll need to use the following

using System.Diagnostics.CodeAnalysis;

See Update libraries to use nullable reference types and communicate nullable rules to callers for a full list of attributes etc.

Loading indicator in Ag-Grid

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

Ag-Grid is a great data grid which supports React (amongst other frameworks). Here’s a couple of simple functions showing how to show and hide the loading indicator using the gridApi

showOverlay = () => {
  if (this.gridApi !== undefined) {
    this.gridApi.showLoadingOverlay();
  }
}

hideOverlay = () => {
  if (this.gridApi !== undefined) {
    this.gridApi.hideOverlay();
  }
}

File explorer extended search in Windows

File Explorer has (as we all know) a search box in the top right, ofcourse we can enter some text and File Explorer will search for filenames with that text and text within files, but there are more options to tailor our search.

See Common File Kinds.

Let’s look at some examples

File name search

If we prefix our search term with file: like this

file: MyFile
file:.sln

Then we only get search results for all files with the text as part of the filename or file extension.

File content search

If we prefix our search term with content: like this

content: SomeContent

Then we only get search results from within files (i.e. text search).

Kind

We can use the kind option along with file type, such as text, music etc. See Common File Kinds.

kind:text

The above list all text files.

Other file options

We can also use the following, other file options, for example finding

datemodified:lastweek
modified:lastweek
modified:05/10/2022
size:>500

The first two options are the same and list files modified last week. The size option lists files with a size larger than 500 bytes.

See also File Kind: Everything.

Boolean Operators

As you can see we can also use Boolean Operators.

XamDataGrid tips and tricks

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

The following is a general list of tips and tricks for working with the XamDataGrid. Primarily code/xaml which doesn’t require a full post of their own.

Enable/disable column sorting or change the way the sorting is applied

Simply set the LabelClickAction on the FieldSettings to “Nothing” to turn sorting off. You can also change the logic for sort in that you can set the sorting to single or multi field.

<igDP:XamDataGrid>
   <igDP:XamDataGrid.FieldSettings>
      <igDP:FieldSettings LabelClickAction="Nothing" />
   </igDP:XamDataGrid.FieldSettings>
</igDP:XamDataGrid>

Changing cell styles and more in code-behind

Sometimes our requirement is too dynamic for the declarative nature of XAML and/or may be difficult to handle via styles/triggers and converters so we need to write some code. The problem is getting at the cell object at the right time.

This is where the CellsInViewChanged event is useful, for example

private void CellsInViewChanged(object sender, CellsInViewChangedEventArgs e)
{
   foreach(var visibleDataBlock in e.CurrentCellsInView)
   {
      foreach(var record in visibleDataBlock.Records)
      {
         foreach(var field in visibleDataBlock.Fields)
         {
            var cellValuePresenter = CellValuePresenter.FromRecordAndField(record, field);
            // do something with the cell value presenter
         }
      }
   }
}

In the above code (which we seem to have to attach an event handler to, i.e. there’s no virtual method for deriving our own implementation from that I can see). We get a list of VisibleDataBlock items which we loop through to get the records and the fields. Using the CellValuePresenter.FromRecordAndField we can then get the CellValuePresenter where we can then change visual style directly, such as the cell background colour, we can make the cell’s editor readonly and so on.

How to stop a cell “appearing” to go into edit mode

We may set a cell’s editor to readonly but when the user clicks on the cell the cell changes colour as if switching to edit more and the caret is displayed, even though you cannot edit the field. A way to stop this happening is by overriding the OnEditModeStarting method in a subclassed grid control or intercepting the EditModeStarting event on the grid. For example

protected override void OnEditModeStarting(EditModeStartingEventArgs args)
{
   // required to stop the cell even entering edit mode
   var cvp = CellValuePresenter.FromCell(args.Cell);
   if (cvp != null)
   {
      args.Handled = args.Cancel = cvp.Editor.IsReadOnly;
   }
}

ASP.NET core and Ingress rules

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

You’ve implemented a service using ASP.NET deployed it to Kubernetes and all worked great, you then deploy a front end to use that service (as per the example in the Project Tye repo) again, all worked well. Whilst the Ingress mapped the path / to your front end services, the CSS an JS libs all worked fine, but then you change you Ingress route to (for example)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: default
spec:
  rules:
    - http:
        paths:
          - path: /frontend
            pathType: Prefix
            backend:
              service: 
                name: frontend
                port: 
                  number: 80

In the above, the rule for the path /frontend will run the frontend service. All looks good so you navigate to http://your-server-ip/frontend and, wait a moment. The front end and backend services are working, i.e. you see some HTML and you see results from the backend service but Edge/Chrome/whatever reports 404 of bootstrap and your CSS.

The simplest solution, but with the downside that you are putting knowledge of the deployment route into your front end service is to just add the following to Startup.cs

app.UsePathBase("/frontend");

Obviously if you’re using tye or your own environment configuration, you might prefer to get the “/frontend” string from the environment configuration instead of hard coding.

Alignment using string interpolation in C#

C#’s string interpolation supports alignment and format options

Alignment

Using the following syntax, {expression, alignment}, we can use negative alignment numbers for left-aligned expressions and positive numbers for right-aligned alignment. For example

var number = 123;
Console.WriteLine($"|{number,-10}|");
Console.WriteLine($"|{number,10}|");

This would produce the following

|123       |
|       123|

See also Alignment component.

Format String

We can use the following {expression, alignment:format} or {expression:format} syntax to add formatting, i.e.

var number = 123;
Console.WriteLine($"|{number, -10:F3}|");
Console.WriteLine($"|{number, 10:F3}|");

would produce the following

|123.000   |
|   123.000|

and

var number = 123;
Console.WriteLine($"|{number:F3}|");
Console.WriteLine($"|{number:F3}|");

would produce

|123.000|
|123.000|

See also Format string component.

Trying out Dapr

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

I’ve been messing around with microservices in one form or another. Once you start down this route (at least in a Microsoft world) you come across Dapr (Distributed Application Runtime). Let’s take a look at what it offers us.

To get started simple visit Getting started with Dapr and follow the steps to install and initialize Dapr, I’m going to reproduce the current steps here for completeness.

  • Install Dapr, I’m doing this on a Linux box hence using
    wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
    
  • Verify the installation by running
    dapr
    
  • Initialize dapr by running
    dapr init
    

    this will download and set up components, which basically means it’s download and then run up openzipkin/zipkin, daprio/dapr and redis docker images, so now we can check those by running

    docker ps
    
  • Dapr creates a components directory, for Linix here $HOME/.dapr and for Windows here %USERPROFILE%\.dapr\

All installed, now what?

Dapr is a sidecar architecture which basically means it exposes HTTP and gRPC either via container or process. So applications do not need to reference Dapr’s runtime instead they use Dapr as a service. The sidecar pattern is classed as a cloud design pattern.

What Dapr’s done is given us some “standard” application combination, accessible via Dapr in an agnostic manner, i.e. via HTTP calls, we can run up an instance of Dapr using

dapr run --apo-id {your-app-id} --dapr-htt-port {the-port-to-access-dapr}

So for example dapr run –app-id myapp –dapr-http-port 3500 will run Dapr up on port 3500 with the app_id of myapp.

The output from the above command will show metrics running on (in my case) port 44333. We can access this from our browser.

By default, zipkin is running on port 9411 (just check docker ps) and can be accessed from your browser using http://{your-server-ip}:9411/zipkin/

As Redis is also running we can access it using the Redis CLI, for example

docker exec -it dapr_redis redis-cli

fetch, no-cors no custom context type

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

If you’re using the Javascript fetch api with mode set to ‘no-cors’ beware that this limits the set of headers you can use in your request. Specifically if you’re trying to interact with a server using application/json, the ‘no-cors’ will simply not apply that content-type.

See Using Fetch

In no-cors mode only the following are allowed

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type which can only take the following
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

Creating a Visual Studio debug visualizer

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

A Visualizer is a feature where, if you run an app. and whilst debugging you put the mouse over a variable a little debugger popup appears. You have a drop down to display the value in the variable as XML, HTML etc.

  1. Create class lib project
  2. Add references to Microsoft.VisualStudio.DebuggerVisualizers.dll and System.Windows.Forms
using Microsoft.VisualStudio.DebuggerVisualizers;
using System.Windows.Forms;

[
    assembly: System.Diagnostics.DebuggerVisualizer(
        typeof(MyFirstVisualizer.DebuggerSide),
        typeof(VisualizerObjectSource),
        Target = typeof(System.String),
        Description = "My First Visualizer")
]
namespace MyFirstVisualizer
{
    public class DebuggerSide : DialogDebuggerVisualizer
    {
        protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            MessageBox.Show(objectProvider.GetObject().ToString());
        }

        public static void TestShowVisualizer(object objectToVisualize)
        {
            var visualizerHost = new VisualizerDevelopmentHost(objectToVisualize, typeof(DebuggerSide));
            visualizerHost.ShowVisualizer();
        }
    }
}

TestShowVisualizer allows us to test from a console app

  1. Create console app
  2. Add reference to Microsoft.VisualStudio.DebuggerVisualizers.dll and our project reference
class TestConsole
{
   static void Main(string[] args)
   {
      var myString = "Hello, World";
      DebuggerSide.TestShowVisualizer(myString);
   }
}

To install, copy to

{visual studio deployment folder};\Common7\Packages\Debugger\Visualizers

i.e. C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Packages\Debugger\Visualizers

and

MyDocuments\Visual Studio 2015\Visualizers