Migrating ASP.NET Core Development Secrets out of appsettings.json

A banner showing an appsettings file filled with fake secrets transforming into one with blank secrets

I’m sure I’m not the only one that has “temporarily” stored passwords, application keys or other development secrets in appsettings.json simply because it was easier or faster than doing it the right way (although if I am, this first sentence will surely come back to haunt me).

I get it. It happens! This blog post actually comes from my efforts to update a project I’m working on with some friends so that we’ve got a more consistent approach to keeping secrets… secret.

So how are we going to go about this? We’ll be using Secret Manager, a fantastically helpful tool built into the configuration API in ASP.NET Core that will let us keep the secrets out of appsettings while not require a change to how we access the settings in code. Sound good?

Throughout the rest of this post I’ll be referring to appsettings.json, appsettings.Development.json and any other configured appsettings files collectively as “appsettings” or “the appsettings files” for simplicity.

Overview

The steps we’ll be taking look as follows:

  1. Configure the project in question to use Secret Manager
  2. Create a secrets.json file containing only the secrets you’re migrating from appsettings
  3. Import that file into Secret Manager
  4. Remove the secrets from appsettings
  5. Test the migration
  6. Commit your changes

Secret Manager

Before we get into the migration itself, it’s worth quickly looking at what Secret Manager is and a bit about how it works.

What is it?

Secret Manager is a tool built into the configuration API in ASP.NET Core. It is designed for exactly the purposes we need it for; storing development secrets in a way that makes them easily accessible in code while keeping them clear of settings files that are committed as part of the project.

How Does it Work?

By default the configuration API will attempt to load values from the configured providers in the following order (with values loaded later overriding previously loaded values):

  1. appsettings.json file
  2. appsettings.{env.EnvironmentName}.json file
  3. The local User Secrets File #Only in local development environment
  4. Environment Variables
  5. Command Line Arguments

What this means is that if you store a value in Secret Manager (the “User Secrets File”), that value will be loaded after (and take precedence over) whatever is in your appsettings files.

The magic of this approach is that (after initial configuration) it’s essentially invisible; the configuration API does all the heavy lifting behind the scenes to retrieve the values from Secret Manager instead of the JSON configuration files without requiring any change to how you access them in code!

Steps

0: Setup

If you’re using CreateDefaultBuilder to create a Host you should already be set up and ready to go, but if you’re using the configuration API directly you’ll need to make sure you register Secret Manager as a configuration provider. The full instructions for setting up your project to support Secret Manager are available in the documentation.

You’ll also need to initialise Secret Manager for any of the projects you’re migrating by doing the following:

  1. Open a command prompt or terminal (depending on your operating system)
  2. Change directory (cd) to the project you’re setting up (wherever your .csproj is stored)
  3. Run dotnet user-secrets init

If everything worked correctly, you should see a message saying “Set UserSecretsId to <GUID> for MSBuild project <ProjectPath>”. If not, you’ll need to make sure you’ve gone through the whole process for setting up your project to support Secret Manager.

You can commit the resultant change to the .csproj that sets the UserSecretsId to source control since the value is only used in the path for the JSON file Secret Manager uses in the background.

1: Preparing the Secrets File

Rather than importing values one-by-one, we’ll be putting together a file with all of the secrets we want to migrate and then importing that file into the Secret Manager tool, so creating this file is our initial goal.

It’s important to remember that secrets in appsettings.Development.json take precedence over those in appsettings.json meaning that if the same secret is present in both files, the value found in appsettings.Development.json is the one that will be used. As an example, let’s say we’ve got the following two files.

appsettings.json

{
  "AllowedHosts": "*",
  "SuperSecretConfigItems": {
    "Password": "ISureHopeThisStaysSecret",
    "AppKey": "12345"
  },
  "NotSecret": {
    "ItemsLoadedPerPage": 20
  }
}

appsettings.Development.json

{
  "SuperSecretConfigItems": {
    "ConnectionString": "ConnectPlease",
    "AppKey": "99999"
  },
  "NotSecret": {
    "ItemsLoadedPerPage": 1000
  }
}

If you were to access the values in the SuperSecretConfigItems element through the configuration API, you’d get the following:

  • Password: “ISureHopeThisStaysSecret” (as it’s only present in appsettings.json)
  • ConnectionString: “ConnectPlease” (as it’s only present in appsettings.Development.json)
  • AppKey: 99999 (as it’s present in both but the appsettings.Development.json value takes precedence)

The fastest way to produce your own secrets file then is as follows:

  1. Make a copy of appsettings.json for the project you’re working on (for simplicity we’ll name the new file “secrets.json”, but if you’re migrating a few projects it might be worth giving it a more specific name)
  2. If you are using appsettings.Development.json (or any other JSON files), copy any secrets into your newly created settings file (secrets.json), overwriting duplicate elements where applicable
  3. Remove any non-secret values (since otherwise they’ll end up in Secret Manager)

Using the above example files, we could expect our secrets.json file to look as follows:

secrets.json

{
  "SuperSecretConfigItems": {
    "Password": "ISureHopeThisStaysSecret",
    "ConnectionString": "ConnectPlease",
    "AppKey": "99999"
  }
}

We’ve removed non-secret values such as AllowedHosts and the creatively named NotSecret element while making sure we get the AppKey value from appsettings.Development.json.

Now that we’ve put our secrets file together, we’re finally ready to move onto the next step!

2: Importing into Secret Manager

Importing secrets.json is thankfully a pretty simple process:

  1. Open a command prompt or terminal (depending on your operating system)
  2. Change directory (cd) to the project you’re setting up (wherever your .csproj is stored)
  3. Import the file by running one of the following commands (depending on operating system)

Windows:

type .\secrets.json | dotnet user-secrets set

Linux/macOS

cat ./secrets.json | dotnet user-secrets set

If the secrets were imported successfully, you’ll see the message “Successfully saved x secrets to the secret store”.

A screenshot of a command prompt in Windows. It shows the command for importing a file into Secret Manager and the result "Successfully saved 3 secrets to the secret store"
I love it when a plan comes together

3: Removing the Secrets from appsettings

Our goal with this post is to remove secrets from appsettings and this is the step where we actually get to do that!

Although you can remove the secrets entirely I prefer to replace them with empty strings, mainly to avoid breaking your required configuration into multiple places. With empty strings (or maybe a placeholder if you prefer) you can see at a glance how the configuration is laid out for the whole project without having to reconstruct it from various sources. Thanks to the previously discussed precedence of configuration sources the values in appsettings will be overwritten by those in Secret Manager, meaning that the actual values you leave behind don’t matter!

Let’s take a look at how our appsettings files look now after that change:

appsettings.json

{
  "AllowedHosts": "*",
  "SuperSecretConfigItems": {
    "Password": "",
    "AppKey": ""
  },
  "NotSecret": {
    "ItemsLoadedPerPage": 20
  }
}

appsettings.Development.json

{
  "SuperSecretConfigItems": {
    "ConnectionString": "",
    "AppKey": ""
  },
  "NotSecret": {
    "ItemsLoadedPerPage": 1000
  }
}

You may also want to remove duplicate entries at this point (such as appkey), preferring to keep the blank entry in appsettings.json over appsettings.Development.json.

4: Testing your Changes

An important step in making any sweeping change like this is to make sure it hasn’t broken anything! How you go about this will depend on your project and what you use the secrets for, but you’ll want to make sure that values are still being loaded and that they are what you expect.

You’ll also have to consider how these changes may impact your testing/staging/production environment(s). If at all possible you’ll also want to test your deployment process to make sure that your environments aren’t relying on the values you’ve removed from appsettings.json!

5: Committing your Changes

If you’ve committed your secrets to source control, this is the time to remove them! My advice is to do this in a separate branch to give other members of your team a chance to get their systems configured correctly before it gets merged into your develop or main branches since it will break the build for anyone who hasn’t moved their secrets to Secret Manager.

Once you’ve managed to get most/all of the potentially impacted developers to set up their environment and all seems to be working correctly you can merge the branch into develop, (relatively) safe in the knowledge that it won’t cause issues for everyone else.

Next Steps

If you’ve made it this far, congratulations! You’ve finished the main process of migrating your development secrets out of your appsettings files and into a more suitable location.

There are now a few more things that you might want to do.

Refresh Secrets

If any of your secrets have made their way into appsettings (especially if they’ve been committed to source control) I highly recommend refreshing/re-issuing them. Consider them compromised! Although you may think they’re safe to keep using, other people with repository access now (or anyone who gets access later) can see and use them.

Once you’ve got the new values, the process to update the settings you migrated is thankfully very simple: modify your secrets.json file and run the import again to overwrite them!

Documenting Setup/Setting up your Team

Now that you’ve migrated your development secrets out of appsettings.json you’ll need to modify any documentation you have for setting up a development environment to include the configuration of Secret Manager.

The process is as simple as taking your secrets.json file and blanking out all of the secret values to turn it into a template. For example, using the secrets.json file from earlier we could produce the following:

{
  "SuperSecretConfigItems": {
    "Password": "",
    "ConnectionString": "",
    "AppKey": ""
  }
}

You can safely commit this file to source control alongside your appsettings files and include steps to fill out and import it as part of initial setup. Committing the file and keeping it up to date is also a very useful way of keeping the setup process as simple as possible to avoid anyone dropping values back into appsettings and undoing your hard work!

Conclusion

You’re done! The above process can take time and attention to do properly, but it’s an important step in ensuring that your development secrets are kept safe.

Electric Bikes and Big Ambitions – EVieBikes Land in Guernsey

A collection of EVieBike branded electric bikes parked together at North Beach in Guernsey

EVieBikes recently landed in Guernsey, bringing the first ever dockless shared electric vehicles to the island. I got into contact with Gavin Breeze (founder and CEO of EVie), who kindly agreed to discuss with me where EVie came from, what the service means for the islands and their plans for the future!

Interview conducted on 2021/04/09.

A Brief History of EVie

According to Gavin, EVie bikes were “sort of all [his] fault”. After founding a software as a service (SaaS) payment company called DataCash and selling it to MasterCard, he found himself at a loose end. Deciding that he was “too young to sit around doing nothing” Gavin looked for his next project, which came shortly after hearing Phil Male (Chairman of JT) discuss a number of ideas he had for improving Jersey. Of the ideas put forth, Gavin decided that “as a private individual the only one [he] could have the […] remotest impact on was to try and move the dial towards the islands becoming all-electric islands” (moving away from internal combustion engine vehicles).

EVie’s first step towards this goal was to move into the shared vehicle hire space, which started with a launch of a couple of cars in Jersey in December 2019 and quickly expanded to a fleet of 10. It wouldn’t be long however until Covid-19 came along, meaning that “people didn’t want to get into a vehicle that somebody else had been [in] 10 minutes before”. Despite this setback, EVie had already sorted out a lot of the difficult parts (such as getting agreements from the Government of Jersey and figuring out logistics for running the service) and so managed to make it out the other side into the current landscape.

Following on from their electric car and van offering, the next step came about when Gavin “suddenly realised that, actually, launching a dockless shared bike fleet was going to be a hell of a lot easier”. EVieBikes were first made available in March 2020 in Jersey with an initial fleet of 140 bikes. Their first year of use was very positive, with 12,000 users taking 50,812 electric bike rides totalling a cumulative distance of 346,649km in 2020.

12,000 users
190 electric bikes
10 electric cars/vans
50,812 electric bike rides
1,810 electric car journeys
346,649km travelled (or 8.7 laps of the Earth!)
3.5 years of cumulative bike rides
45.8 tonnes of CO2 SAVED

Gavin Breeze

After realising that most EVieBike users were not bike owners themselves but might have an appetite for medium-term ownership EVie began their BlueBike service, a subscription scheme that allows for users to get full-time access to an electric bike without having to commit to purchasing one.

In early April 2021 EVie expanded into Guernsey with an initial set of 25 EVieBikes after talks with Deputy Lindsay De Sausmarez (President of the Committee for the Environment & Infrastructure) indicated that the island would be welcoming of such a platform.

An EVieBike branded electric bike parked at the bike racks outside M and S in St Martin, Guernsey

EVie in the Present

The Target Markets of EVieBikes

Although EVieBikes can be used to get around as with any other bike, Gavin mentioned that they’re aiming for three main target markets:

  1. Tourists (when they’re allowed back in the islands)
  2. Commuters
  3. People running daytime errands

The parking situation in Guernsey was raised as a particularly large factor influencing this. After talking about the lengths that many Guernsey residents go to in order to secure a town parking space in the morning, Gavin mentioned that “if you do have to pop out at some time during the day you’re very reluctant to do it because you’re going to lose your car parking space! Whereas if you could just jump on a bike, keep your car parking space for when you want to go home in it and pop out and do your 10 minutes down the road, then why not?”.

Running a Responsible Dockless Bike Platform

Even after figuring out the logistics and operations required to bring EVie to the islands, operating the service is no mean feat. Phil Le Poidevin is EVie’s “man on the ground” where he is in charge of the Guernsey rollout and looking after the fleet, moving the bikes around to anticipate demand and to make sure that the bikes aren’t left scattered across the island.

Although Phil is indispensible in making sure that the bikes are where they can best be used, Gavin noted the importance of incentivising responsible behaviour from users as well: “There are a couple of ways in which we can do that. One is to try and encourage people to actually return their bike to a geolocated virtual bike rack. […] The other layer on top of that is what we call ‘yellow zones’. A ‘yellow zone’ is a demarked area where […] you simply cannot end your rental”.

These measures are intended to push users to utilise the service in a way that doesn’t negatively affect other islanders. “What we don’t want is people leaving bikes (especially in town) in stupid places. […] Having people park responsibly is incredibly important to us” said Gavin.

EVie are constantly making changes based on user feedback and they hope to apply the lessons they’ve learned from the “painful experiences […] in Jersey” to their Guernsey rollout of the service.

The Good and the Bad of Operating in the Channel Islands

Guernsey and Jersey both bring unique benefits and challenges to operating a platform such as EVie. On the positive side Gavin mentioned how range anxiety (the concern for electric vehicle users that they’ll not be able to make it to the next charging station with their current range) isn’t a problem for islanders as it might be in the UK, saying that “You’d really have to be driving around pretty hard to get through a battery in a day”.

On the negative side however is the dispersed nature of housing in the islands compared to a densely populated city in the UK since the bikes tend to migrate to lower traffic areas over time. Gavin went on to say “It’s very much easier to make money and make a fleet run efficiently if you’ve got high density areas where within that [area] you don’t really mind where the bikes are going to be left because you are pretty sure that somebody else is going to rent them from the same place. […] In Jersey and Guernsey, that’s not the case.”

A closeup of the drivetrain and livery on an EVieBike branded electric bike

The Future of EVie

Guernsey Expansion

For the moment EVie are focusing on the rollout of EVieBikes in Guernsey and the expansion of their local dockless fleet to 100 bikes, but the ship Ever Given getting stuck in the Suez Canal caused the second batch of 75 bikes to be delayed.

Further expansion of the services offered in Guernsey were discussed, but these are highly dependent on overall reception of the project as well as the political landscape in the island. Although the platform began in Jersey, Gavin mentioned that he had a “sneaking suspicion that one or two things are actually going to end up being launched in Guernsey before they are in Jersey because of the different attitude and different approach to transport”.

The Move to a New Platform

While the current EVieBikes and the platform they run on are both created by Freebike, EVie are planning on moving to a new bike supplier and separate software platform in the near future. Explaining the move, Gavin said “unlike in Jersey where the cars are on one stack and the bikes are on another stack, […] what will be being rolled out in the next week or so in Jersey is a new car app and then as soon as the new bikes arrive [they] will be hooked up onto the same platform and you’ll be able to see both the bike availability and the car availability from the same place”. Currently the electric car offering in Jersey is only available through the EVie app itself, with the bikes being accessibile separately from the Freebike app. This move will allow for a more consolidated and simpler view of what transport is available throughout the island.

The new platform will also allow EVie to easily add other mobility types they may release in the future (such as e-scooters or e-mopeds), grant them flexibility to support a more diverse set of electric cars and bikes and consolidate user membership into one place. Gavin went on to mention that the shared data “also allows us to be an awful lot cleverer in the fleet optimisation, so understanding where the heaviest points of traffic are and making sure that our fleet admin operators are slightly more agile and effective in putting bikes and cars where they’re most likely to be used”.

EVie’s electric cars in Jersey will be the first to migrate to the new platform with the electric bikes following after the set from the new supplier arrive in Jersey. The opposite approach was originally planned (with bikes migrating to the new platform first) but shipping delays forced EVie to reconsider their approach.

Battery Recharging

One of the ideas that EVie are looking into is that of an easier battery recharging/switching system which would allow for users to swap out batteries at recharge stations situated in key locations throughout the islands.

This could help alleviate some of the effort required from EVie to keep the batteries across the fleet charged while allowing for more user flexibility as even bikes with a low charge could still be utilised with a quick battery swap granting a larger/full range.

User Incentives

Although very much still in the concept phase, Gavin mentioned the possibility of introducing user incentives: “We might for instance post a bulletin saying that ‘bike number 67 is sitting at this crossroads and is out of station, anybody who brings it into town we’ll give them a free ride credit’. If somebody lives relatively close by and they were going to go into town anyway then why not pick up the bike and move it to somewhere that it’s more useful?”.

Such a system would benefit users who are willing to jump on any incentives offered whilst also saving EVie operators from having to relocate bikes that may otherwise be spread out a long distance from each other.

A Consolidated Payment System for Public/Shareable Transport

When discussing the future of the EVie platform itself, Gavin remarked “If you think about it, what we’re sitting on is a payment wallet. […] It would be very easy for us to use the QR code functionality of the app to [scan] a code sitting in a bus”. Rather than having different forms of public transport operating with entirely distinct payment systems, an EVie “wallet” could allow for a greater flexibility for islanders by giving them the option of using the EVie system to pay for all kinds of transport, streamlining the process if they wanted to (for example) catch a bus into town and then rent a bike to get closer to their final destination.

Park and Ride Scheme

In-town parking has a cost associated with it in Jersey, but this cost often depends on its location (mainly how close to the centre of town it is). EVie are looking to help with this by turning the furthest away locations into “Park and Ride” stations, allowing for people to park in a cheaper location and making the rest of their journey on bike. “With a bit of luck it will encourage more people to use those parking places for their cars rather than fighting for one in town, driving [round] in circles looking for a free space” Gavin said.

Conclusion

Personally, I’m really excited to see what EVie will bring to the islands over the next few years. I’ve already tried out the service myself and will be writing a separate post about that soon (so keep an eye out for that!) but I can definitely see myself using it in the future.

A huge thank you to Gavin for his time and willingness to answer all of my questions. Our half hour interview quickly spiralled out to last over an hour and I’m sure we could have both continued talking for far longer if we had the time!

Multi-Factor Authentication with Password and Private Key File in SSH.NET

If you want to use SSH.NET to connect to an SFTP server that requires both a password and a private key file, you’ll be happy to know that it is well supported! Unfortunately (and similar to my previous SSH.NET post about modifying the Host Key Algorithm) the documentation doesn’t really make it clear how to do this.

As an example, let’s grab the code sample from the SSH.NET documentation on multi-factor authentication. At time of writing it looks as follows:

var connectionInfo = new ConnectionInfo("sftp.foo.com",
    "guest",
    new PasswordAuthenticationMethod("guest", "pwd"),
    new PrivateKeyAuthenticationMethod("rsa.key"));

using (var client = new SftpClient(connectionInfo))
{
    client.Connect();
}

If you modify the server address, username and password and then run it you’ll quickly hit a brick wall in the shape of this error message:

Renci.SshNet.Common.SshAuthenticationException: Permission denied (publickey).

The first issue that we’re running into is that we’re not actually specifying the private key details anywhere! Let’s change that (I’ve also swapped the literal strings out for some variables):

string _privateKeyPath = "";
string _privateKeyPassPhrase = "";
string _host = "";
string _username = "";
string _password = "";

var keyFile = new PrivateKeyFile(_privateKeyPath, _privateKeyPassPhrase);
var keyFiles = new[] { keyFile };

var connectionInfo = new ConnectionInfo(_host, _username,
    new PasswordAuthenticationMethod(_username, _password),
    new PrivateKeyAuthenticationMethod("rsa.key", keyFiles));

using (var client = new SftpClient(connectionInfo))
{
	client.Connect();
}

Now if you run this you’ll get a new error (#ProgressIsProgress), this time telling you that you’re not allowed to change username:

Renci.SshNet.Common.SshConnectionException: The connection was closed by the server: Change of username or service not allowed: (<USERNAME>,ssh-connection) -> (rsa.key,ssh-connection) (ProtocolError).

Now when I first ran into this error and threw it into Google I got very few results; looks like we’re treading new ground!

The fix for this is actually really simple; the constructor for PrivateKeyAuthenticationMethod takes a username as the first parameter! For some reason this is set to “rsa.key” in the official documentation rather than “guest” which they use as the username placeholder on the two lines above, so when I first looked into this issue I wrongfully assumed that it was a string specifying what type of private key was being consumed!

The only change we need to make to the previous example is to swap in the _username variable (or a literal string of the username if you prefer) for the first parameter of the PrivateKeyAuthenticationMethod constructor.

string _privateKeyPath = "";
string _privateKeyPassPhrase = "";
string _host = "";
string _username = "";
string _password = "";

var keyFile = new PrivateKeyFile(_privateKeyPath, _privateKeyPassPhrase);
var keyFiles = new[] { keyFile };

var connectionInfo = new ConnectionInfo(_host,
    _username,
    new PasswordAuthenticationMethod(_username, _password),
    new PrivateKeyAuthenticationMethod(_username, keyFiles));

using (var client = new SftpClient(connectionInfo))
{
	client.Connect();
}

Run it now, and you should connect successfully!

Regular Expression Tips for People That Hate Regular Expressions

A screenshot of a code editor. There are three lines, setting the variables "isCustomerNumber", "isProductNumber" and "isTransactionNumber" based on whether a series of regular expression (regex) matches succeed

I’ve been writing regular expressions (regex) for years and would consider myself pretty good at them by now (I decline to provide references). The problem is that although it’s common to see regex as cryptic and painfully terse (which are not invalid points), they remain one of the best ways to handle complex pattern matching and as such you’ll probably run into them at least a few times in your career.

Even if you really despise writing regular expressions, here are some tips that will help to make that process as painless as possible!

Continue reading “Regular Expression Tips for People That Hate Regular Expressions”

Epson ET-2711/ET-2710 Series Printer Wireless Setup Made Easy

A photo of an Epson ET-2711 printer

If you want to just get to the good stuff, scroll down to the “Setup” section.

My wife and I finally got a new printer to replace the old one that has pretty much given up the ghost and refuses to print anymore (often considered an important feature for devices like this).

We settled on an Epson ET-2711 in large part because of the ink tank that should (hopefully) do away with the constant stream of expensive cartridges in favour of some cheaper-per-page ink bottles. I was excited to get it out and start setting it up (in part because we’re in another lockdown and what else is there to do right now)!

Imagine my frustration, dear reader, when I found out that the whole wireless setup process for this printer is terrible if you follow the official instructions. I genuinely spent a couple of hours bouncing between the Android app (which gave me a very helpful message telling me “Communication error”, to check the printer is on and not much else), the included software for Windows (which was just as helpful), the printed documentation in the box and the website, all to no avail.

You cannot convince me that this is a helpful error message

The good news is that I finally figured out how to get it working. The even better news for you at home is that I’ve gone through the process three times so that I could document all of the steps to get this working properly!

Continue reading “Epson ET-2711/ET-2710 Series Printer Wireless Setup Made Easy”

Migrating from KeePass to 1Password

An image of the KeePass and 1Password logos, with an arrow pointing from KeePass to the stylised "o" in 1Password

I’ve been using KeePass for my password management needs since early 2014, but I recently decided that I wanted to move to something a bit more substantial. KeePass is an excellent (open source!) piece of software, but since it stores passwords in a single database file the only way that I could really sync it between multiple computers and my phone was to store that file… in Dropbox.

Yeah, as you can imagine that’s not a great solution.

Anyway, I wanted to move over to 1Password but when I tried searching for “Migrate KeePass to 1Password” I kept seeing references to 3rd party scripts I’d need to use to convert my exported data (no thanks) or that it would require a bunch of manual data entry. After giving it a go though, I can tell you it was actually ridiculously easy and straightforward and didn’t require any external tools or scripts! As such, I decided to put together this step-by-step tutorial for migrating your data from KeePass to 1Password!

Continue reading “Migrating from KeePass to 1Password”

So You Want to Run Azure Functions Using .NET 5

UPDATE 2021/11/09: Since the release of .NET 6 yesterday, there is reportedly day 0 support for .NET 6 across App Services and Azure Functions. Unless you have an absolute requirement to use .NET 5, the solution to using the latest and greatest .NET in Azure is .NET 6! I’ve left the rest of the blog post as it was just in case it helps someone, but I predict that it will become something of a relic now that it’s targeting an older version.


I’ve spent the last couple of evenings trying to get a set of Azure Functions migrated from .NET Core 3.1 to .NET 5 so that I can play around with some of the nice new syntax options, nullable contexts and the like. Since .NET 5 has officially been released, it would be justifiable to believe that it would be well supported across the core Microsoft product catalogue, such as in… say… Azure Functions?

Ha! You’re a funny one.

Continue reading “So You Want to Run Azure Functions Using .NET 5”

There Is No Such Thing as a New Idea, and That’s Ok!

A lightbulb laying on a chalkboard, with a thought bubble drawn around it in chalk

Mark Twain once wrote that “there is no such thing as a new idea” and quite frankly I’m starting to agree with him.

I’ve spent the last month or so actively trying to come up with some ideas for projects/ blog posts to work on that would be interesting and useful. The issue I’ve run into is that almost every time I come up with something, I give it a quick search only to find out that it’s already been done (sometimes many times over). That means another idea goes on the pile to be abandoned since “there’s no point in doing it anymore I guess”.

Well that’s not a fun feeling to have.

Changing Host Key Algorithm in SSH.NET

I’ve used SSH.NET a lot over the years to send and receive files using SFTP and it’s a very flexible and practical library, but the documentation can be a bit thin on the ground when you’re looking to use some of the more esoteric features it has.

As an example, I recently ran into an issue where I was connecting to a remote server and the host fingerprint I was receiving through SSH.NET didn’t match the one that I expected to see (and could see in WinSCP). After verifying that I was using the same connection settings on both and more than a little spelunking through the SSH.NET source code I found that by default the host key algorithms used by the stable release of SSH.NET that I was on (2016.1.0) are RSA and DSA, while WinSCP uses Ed25519. For my purposes I needed to use Ed25519 in SSH.NET as well even though the SFTP host also supported these other algorithms.

Continue reading “Changing Host Key Algorithm in SSH.NET”

SoundFloored: Open Source Soundboard Pedal (Part 4 – Final Implementation)

The top of the SoundFloored pedal. It is held together by various cross-head bolts and has six footswitches embedded in the top, with four along the close long edge and two along the far long edge (with a screen embedded in the lid between them)

This is the fourth and final post in a series about designing and creating SoundFloored, an open source soundboard pedal! Check out the other posts in the series:


So SoundFloored is now working just like I wanted it to with buttons and a screen, but the current build isn’t exactly what I would call robust. As such, the final part of the build involves moving what I’ve built so far into a more permanent home, one that can withstand the rigours of live performance and is far more practical to move around.

Building the Box

Design

Based on some preliminary research on the minimum usable distance between footswitches, I decided to keep them 7cm apart from each other to ensure good clearance. I also thought to leave a 3.5cm gap between the switches and the edge of the pedal since I didn’t need as large of a gap but still wanted the numbers to map out in a simple way.

Since there were going to be four footswitches across the length of the pedal, it would need to be 28cm long (3 x 7cm for the gaps between each switch, plus 2 x 3.5cm for the gaps between the outer switches and the edge). Similar maths for the two footswitches going across the width of the pedal gives us 14cm (7cm for the gap plus 2 x 3.5cm for the edges).

I wanted to find something with these dimensions (or near enough) that I could use to house everything, so I started by looking at “project boxes” (plastic boxes designed for maker projects like this). Unfortunately, the largest project box I could easily order was barely half the size that I needed and I wasn’t interested in putting in a custom order to create one. The only option left at this point was to build something myself!

I figured that wood would be the best material for this project; although not the traditional material for a pedal, I could make it pretty much whatever size I wanted, it’s readily available, cheap and I already have some basic experience in woodworking.

At this point even though I had the dimensions I wanted to get a better perspective of how big the pedal was going to be before I started building anything. Mediocre arts and crafts to the rescue!

Continue reading “SoundFloored: Open Source Soundboard Pedal (Part 4 – Final Implementation)”