Using ToLower() or ToUpper() in C# to compare strings is not safe in all cultures

If you’re using Resharper, Roslynator or similar you’ll likely see string comparisons using ToLower() or ToUpper() flagged.

Why?

Well these comparisons are not safe in all cultures. The canonical example is the ‘Turkish i problem‘ which relates to how in Turkish the dot is present on the top of the uppercase version of ‘i’ and there is no dot on the lowercase version of the ‘i’. This means using .ToLower() etc. may return different results on machines with different culture settings.

On their Best practices for comparing strings in .NET page Microsoft recommends using StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase for comparisons as your safe default for culture-agnostic string matching.

StringCompare example in C#

Aside from safe comparisons, StringComparison also expresses intent more clearly and does not need to create strings so there’s a potential performance boost too.

Use SQL Server Sparse columns to optimize storage for columns with mostly NULL values

If your SQL Server database has nullable columns which contain mostly null values consider setting these columns to sparse. Sparse columns are ordinary columns that have been optimized for storing null values. Not all columns can be set to sparse and a number of restrictions apply.

How to set sparse

Columns set to sparse require more storage space for nonnull values (4 additional bytes) than the space required for identical data in a column that is not marked sparse. This means it only makes sense to use sparse when the percentage of nulls is above a certain threshold. The threshold is different for each data type.

An except from Microsofts Estimated Space Savings by Data Type table is below. The red highlight shows how many bytes are needed for normal non sparse columns, this is regardless if they are null or not.

The blue highlight shows bytes required for non null values in sparse columns. Note null values take up 0 space in sparse columns.

The final column shows what percentage of nulls is needed for space saving of 40%. Microsoft recommends using sparse columns when savings are at least 20 – 40%. We can see in yellow that to save 40% space for int columns we need 64% of values to be null, while the corresponding percentage for datetime columns is 52%.

Sparse fixed data types

Determining percentage of null values in a column manually

Pretty simple..

SELECT 100.0 * SUM(CASE WHEN Address4 IS NULL THEN 1 ELSE 0 END) / COUNT(*) from Address AS Address4NullPercent

where Address4 is your column and Address is your table name.

Determining percentage of null values in all columns in all tables dynamically

If you have a large DB and wish to check for sparse candidates across your entire database you can use the script on this page which uses temporary tables and cursors to do this dynamically.

Note the script referenced above might take a while to run so to prevent performance issues for your existing prod processes its best to run it either after hours or on a production clone. It will produce a table similar to below.

sparse-candidates

You’ll get the biggest space savings from using sparse columns with fixed-length columns having a high null percentage in tables with large amounts of records.

Finding which columns are already sparse

SELECT so.name [Table Name], sc.name [Column Name]
FROM sys.columns sc
JOIN sys.objects so
ON so.OBJECT_ID = sc.OBJECT_ID
WHERE is_sparse = 1

 

Enabling WebP images to show on Blacknight windows hosting

If you’ve uploaded a WebP file into your Blacknight windows web space but are getting the below message when trying to request it in your browser…

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

it means the .WebP extension is not recognized as there is no .WebP MIME type added to Blacknight windows servers by default. To resolve just requires you to add the WebP MIME type.

When you log in to your control panel navigate to Websites -> yoursite.com -> WebSite Configuration -> MIME Types and add the type as below.

Adding WebP mime type on Blacknight

It might take a minute or two to take affect but you don’t need to explicitly stop and start your website.

MVC Razor views not refreshing after changes to .CSHTML in .NET Core 3

Since .NET Core 3.0 your views in MVC won’t refresh after you change your .CSHTML markup. According to Microsoft this functionality was removed as a consequence of cleaning up the ASP.NET Core shared framework to not depend on Roslyn.

To have your views refresh in .NET Core 3+ you need to install the below package from NuGet

Install a package

and then enable it from your Startup.cs file.

Add services

Use Visual Studio Code keyboard shortcuts in Visual Studio

If you use both Visual Studio Code and Visual Studio and don’t want to have to remember two different keyboard shortcuts for every command you can easily configure Visual Studio shortcuts to be consistent with those in Visual Studio Code. This can be setup from the Tools -> Options -> Environment -> Keyboard settings screen.

Visual Studio Code Keyboard shortcuts in Visual Studio