Tuesday 17 November 2020

10 VS Extensions You Might Have Missed

I presented a lightning talk tonight at DotNetOxford on '10 VS Extensions You Might Have Missed' covering some perhaps lesser-known items in the Visual Studio Marketplace. All of these extensions are free, and they all provide a useful addition to what you get out of the box in Visual Studio.

UPDATE: And now you can see the whole evening's set of talks at https://www.youtube.com/playlist?list=PL4qgjzgv2UYTTCbWELKjyJrcKMz02K7DH


Customize Visual Studio Window Title

https://marketplace.visualstudio.com/items?itemName=mayerwin.RenameVisualStudioWindowTitle


Azure DevOps Status Monitor

https://marketplace.visualstudio.com/items?itemName=UtkarshShigihalliandTarunArora.VSTSStatusInspector


Viasfora

https://marketplace.visualstudio.com/items?itemName=TomasRestrepo.Viasfora


Tweaks

https://marketplace.visualstudio.com/items?itemName=MadsKristensen.Tweaks


Trailing Space Visualizer

https://marketplace.visualstudio.com/items?itemName=MadsKristensen.TrailingWhitespaceVisualizer


Web Essentials

https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebEssentials2019


Const Visualiser

https://marketplace.visualstudio.com/items?itemName=MattLaceyLtd.ConstVisualizer


Warn About TODOs

https://marketplace.visualstudio.com/items?itemName=MattLaceyLtd.WarnAboutTODOs


Snippet Designer

https://marketplace.visualstudio.com/items?itemName=vs-publisher-2795.SnippetDesigner


Stack Trace Explorer

https://marketplace.visualstudio.com/items?itemName=SamirBoulema.StackTraceExplorer


I hope everyone got something out of this and found at least one extension that might be useful for them!

Sunday 27 September 2020

ASP.NET Bundling and http 403 Errors

 So I'm probably late to the game in running into this, but it bit me at work last week and I thought it was worth writing up...

I made a change to one of our internal websites that involved bringing in FontAwesome so I could use some of it's widgets. I downloaded the FontAwesome CSS and font files to serve them from our internal server, and I added them to my project under the Content folder, and I created a new StyleBundle that referenced the CSS file so I could get that sweet minification. I ran up the site on my laptop and there were my new widgets. Cool. I committed and pushed my changes, had my pull request accepted, and Azure DevOps deployed the new build to the server. I ran it up on the server - and my widgets weren't showing. But, but, but, it Works On My Machine. Time for some investigation.

My first stop was to look at the console in Chrome, where there was an important clue:


A http 403 error? But where was that coming from and how did it relate to FontAwesome? Step 2 in my investigation, look at the raw request in Fiddler and see where the 403 is coming from.

So, the first request produces a 301 result, which for those of you who haven't memorised the http status codes is 'Moved Permanently' and provides a Location in the response headers for the browser to redirect to. Notice in the Fiddler screenshot that the 301 result is generated by a request to /Content/FontAwesome, which corresponds to the name of my bundle, but the 403 result comes from /Content/FontAwesome/ - which corresponds with the path in my project that I put the FontAwesome CSS files into. 
So, there's an issue with bundling when your bundle name matches a path in the file system, and the result is this 301-403 dance where your CSS files doesn't get loaded. And the solution is obvious - don't give your bundles a name that matches a path in the file system. In my case, I renamed my bundle from ~/Content/FontAwesome to ~/bundles/FontAwesome and all was right with the world.
Why did it work on my machine? Well, in one of those 'obvious in hindsight' things, I forgot that when you have debugging enabled in your web.config, ASP.NET bundling doesn't take effect and your files that would go through the bundling are actually served straight from the file system. When I ran my code locally without debugging, I saw the same behaviour on my machine. 
Why did I pick a bundle name that matched the file system in the first place? Simple - I was following the same pattern as the boilerplate bundling code gives you for StyleBundles:
bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css"));

All the above relates to .Net Framework ASP.NET sites. What happens in ASP.NET Core and can you have the same issue? Well, if you go down the bundling route in ASP.NET Core, it works differently and your bundling code produces a file for you to include in your markup rather than a virtual directory. Which means there shouldn't be an issue of a virtual directory name clashing with a physical one. See the MSDN documentation for bundling here.

Monday 10 August 2020

Linq vs Regex

I recently had to write a password validator as part of a technical test for a prospective employer, where three of the conditions were:

  • Passwords must contain an upper case character
  • Passwords must contain a lower case character
  • Passwords must contain a number

Having recently had occasion to learn that you can treat a string as a collection of characters and then use Linq to run set operations across the collection, in the test I used this code:

password.Any(char.IsUpper)

password.Any(char.IsLower)

password.Any(char.IsDigit)

But I worked through the same test again yesterday as an exercise with a friend, and we used Regex instead, so the code became:

new Regex(@"[A-Z]").IsMatch(password)

new Regex(@"[a-z]").IsMatch(password)

new Regex(@"[0-9]").IsMatch(password)

Plainly either version works; I don't see myself as a great Regex developer, which is partly why I reached for the Linq solution first. But seeing the solution written both ways I got to wondering if there was a performance benefit one way or the other. Clearly, there's only one way to find out...

I wrote up a console app that would use a Stopwatch to time each operation, and I ran it over 100 iterations and reported the average number of ticks taken (I started off measuring the number of milliseconds taken but this was zero...). 
And we can see that in two cases the Regex outperforms the Linq version, and in the third it's more or less even. Job done!

But... what happens if we up the number of iterations? Here's the same code run across 1 000, 10 000 and 1 000 000 iterations.

Across more iterations, the Linq version performs faster!

So which should you use? Well, as with most things programming, it depends... It's important to remember that we're talking about differences of only a tick or two, measurements so small that your user won't notice. So with that in mind, we should think about other considerations, like our relative skill levels between Linq and Regex, and which version we find more accessible and readable. So for me, if I was making the choice I'd opt for the Linq versions; I tend to find Regex somewhat impenetrable. But you might make a different choice, and that's fine too.

If you want to try my code (and the performance might be different on your machine), my code is at https://github.com/philpursglove/LinqVsRegex

(Aside: I was very pleasantly surprised to find the tooling support for writing Regexes in Visual Studio has massively improved, when you start writing your expression now you get Intellisense that shows you some of the options, and you get colour-coding inside your expression that helps you identify the parts of your expression)


Update: After I posted this, Steve got in touch to say that compiled Regexes may offer a performance benefit. You specify that a Regex is compiled by adding an option into the constructor:
new Regex("[A-Z]", RegexOptions.Compiled)
When a Regex is compiled, it is converted to MSIL and executed by the JIT compiler, and the MSIL is then cached by the regular expression engine. The price you pay for this is a longer startup time as the compilation happens, but then you get a faster execution. (Microsoft has a whole article on best practices for Regexes that covers this and some other considerations, and there's another piece about compilation and reuse of Regexes).
So let's kick the tyres on this... I added a switch to my code that allows you to switch compilation on and off. Here's some numbers over 100 iterations with compilation on.
We can see immediately that the startup impact of compiling the Regex adds an order of magnitude of overhead to our code (but remember that the practical impact of this is probably still only a matter of milliseconds), and over a relatively small number of iterations this means it will be significantly outperformed by the Linq solution. If we up the number of iterations, does paying that upfront cost return us any kind of performance dividend? Here's the same code over 1 000 000 iterations.
Over more iterations, the upfront cost of compiling the Regex gets amortised down, but (on average) it still gets beaten by Linq (and I've also tried it over 10m and 100m iterations and this pattern remains consistent). 
So Linq is consistently better, yes? Maybe, maybe not... For one thing, the Regexes I'm using are pretty simple - I have a sneaking suspicion that a compiled, more complex Regex would turn out to beat a number of chained Linq expressions. Some of the other options for Regex may also have an impact.

Steve also pointed me to Benchmarkdotnet to look at other aspects such as memory usage to get a fuller picture not only of which method looks better from the raw timings but also in terms of memory usage etc, which I may look at in a future post...

Saturday 25 July 2020

Controlling Your Costs With Azure Policy

I made a mistake. I've been trying to figure something out in Azure, and I needed a website to do it with, so I spun one up on a new App Service Plan. I missed that the default plan is a premium plan, and I only noticed this the other day. In the meantime, my site has been racking up charges, and as a result my Azure bill for July is going to be ... about £100. 

Which is (kind of) fine, experience is the best teacher, it's my mistake and I'm going to own it. It's not a problem-causing amount of money for me. And I'm not averse to spending that kind of money on Azure services on purpose, it's just not the sort of thing I want to be doing again by accident.

Fortunately, I know by using Azure Policy that you can put all kinds of controls in Azure to stop people doing this sort of thing and ending up costing your company lots of money, so I've put the same kind of control in for myself.

What I need is a policy that stops me creating any more premium App Service Plans, and this is not that difficult to achieve.

Policies work on an 'if-then' model, you give the 'if' clause a set of conditions and if the set of conditions matches, then the 'then' clause fires. So in my case when I'm creating a new Azure resource my conditions will be: the resource type is an App Service Plan, and the SKU name is not set to 'F1', and my action will be to stop the action i.e. prevent the resource from being created.

Policies are written in JSON, you can write them directly in the Azure Portal, there is also a VSCode extension to help you with creating them. Here's a skeleton policy:

"policyRule": {
    "if": {
      }
    },
    "then": {
      "effect"""
    }
  }

Effects can be any of a number of values, including "deny" which disallows the action completely, "audit" which allows the action but logs that your policy is being violated, and a number of others including some that will change your action to make it comply with your policy.

So clearly the effect in my then clause needs to be "deny", so that it correctly prevents the action. Which leaves me to work out what the correct if clause is. As I said above, I have two conditions, so I'll be using the allof condition which translates to an AND operator (there is also anyof which is the equivalent of OR). My first condition is that I want the policy to act on App Service Plans, so I'll need to be looking at the type of thing that's being created. Policies use a system of aliases for types (with namespaces), there are two ways to find the alias you want. The hard(er) way is to use the Azure command-line tool to query a list of available aliases as suggested in the documentation e.g.

az provider show --namespace Microsoft.Web --expand "resourceTypes/aliases" --query "resourceTypes[].aliases[].name"

The easy way is to go through the resource creation process in the Azure portal, through to the 'Review and Create' step. Once there, don't create the resource, but download the ARM template, and then search through it for the 'resources' element; inside the resources element, look for a 'type' property, and the value of the property is the alias you want. Which tells me that for an App Service Plan, the alias I should be using is 'Microsoft.Web/serverfarms'. On to the SKU value! I need to look at a property of a serverfarms object and check whether or not the value is 'F1' (the name of the free tier). And if we go back to the command-line query and browse the results, we can see that under Microsoft.Web/serverfarms there is a sku.name property; we can use that with a 'notEquals' operator to check the value.

So our whole policy looks like this:

"policyRule": {
      "if": {
        "allof": [
          {
            "field": "type",
            "equals": "Microsoft.Web/serverfarms"
          },
          {
            "field": "Microsoft.Web/serverfarms/sku.name",
            "notEquals": "F1"
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }

I applied this policy to my subscription, and here's what happens if I now try to create a premium service plan.

Note that the policy evaluation happens in the review stage, before the resource is created.

We've looked here at creating a basic (but useful!) Azure policy to restrict creation of a premium Azure resource, and you can apply that to your own subscriptions to help keep you from making the same mistake I did. And this is only a taste of what you can achieve with Azure Policy.

(And now I'm protected from accidentally creating any more premium App Service Plans - but I could create a premium database, or a storage account, or a VM... Hmm, maybe I need to go write some more policies...)

Thursday 23 April 2020

Reading and Writing Azure KeyVault Secrets with C#

Every application has secrets of one kind or another; database connection strings, API keys or other credentials are all common examples and you can probably think of others without having to try too hard. So every application needs to be able to store, read, update and remove secrets. 

Azure KeyVault is the Azure store for securely storing and accessing secrets, in this blog I'm going to go through how to setup a C# application to get your secrets in and out of KeyVault.

So I've set up a KeyVault through the Azure portal, and I've added a secret to it.


The next thing we need to do is set up a principal in Azure Active Directory; this will give our application a context by which it will be able to access the KeyVault. This can also be done through the Azure portal by entering 'Active Directory' in the top search bar. Once in the AD blade, you need to create a new app registration, so click on 'App Registrations' in the menu and then click 'New Registration'. You'll need to enter at a minimum a name for your registration, and you can optionally enter a URI that receives an authentication token. I'm not entering one here as my demo will just be a console application, but you might need one depending on your individual applications. Note that if you do enter a URI, it must be either secured by SSL e.g. https, or it must be a http://localhost address.

Once the registration is created, you'll see it in the portal. You can see the clientId here, which we'll need later.
We'll also need to create a secret that our application will use to prove its identity to AzureAD when we try to request an authentication token. (Think of the clientId and secret as being like a username/password combination). Click on Certificates and Secrets in the menu, and then click the New Client Secret button. Enter a description and how long the secret should be valid for, and create the new secret. Like the clientId, we'll need the secret later, so make a note of it now as you will not be able to view it later on.
With the App Registration setup, we now need to associate that with the KeyVault. Return to your KeyVault in the portal, and click Access Policies in the menu. To allow the app to access the KeyVault, click the Add Access Policy link. Here you can set the permissions that your app will have against your vault. There are a set of predefined templates you can use, or you can assign individual permissions. For now, I just want to read and write secrets, so in the Secret Permissions dropdown I'll just select Get/List/Set/Delete.
With the permissions selected, you need to associate them with the principal we created in Active Directory. Click Select Principal to open the blade. You'll see a whole set of standard principals, so the easiest way to find the correct principal is to enter the name in the search box.
Once you've selected the principal, click Add to close the blade. And then click Save to save your application's access policy.


With all that prep work done, we can go write some code!

In Visual Studio, start a new .NET Core Console app, and add the Nuget packages Microsoft.Azure.KeyVault and Microsoft.IdentityModel.Clients.ActiveDirectory to it. 

The KeyVaultClient class is what we'll use to perform operations against the vault; it has a number of different constructors depending on your scenario, the one I'm using takes an AuthenticationCallback delegate. 
KeyVaultClient vaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Program.GetToken));


The GetToken method's signature must match what the delegate expects - three string parameters for authority, resource and scope, and, probably because I don't deal with delegates very often, this was the part of this I found the most confusing as I couldn't see where they were coming from. The answer is that they are filled in by the callback at runtime, you don't need to supply the values yourself at any point. This is also where the clientId and secret we created earlier come in. Here's a sample GetToken method.
private static async Task GetToken(string authority, string resource, string scope)
{
    ClientCredential credential = new ClientCredential(clientId, clientSecret);

    var context = new AuthenticationContext(authority, TokenCache.DefaultShared);

    var result = await context.AcquireTokenAsync(resource, credential);

    return result.AccessToken;

}


Once we have a KeyVaultClient instance, we can start to query our vault. Your goto methods are most likely to be GetSecretsAsync, GetSecretAsync and SetSecretAsync, but there's a whole raft of methods for managing keys, secrets and certificates. GetSecretAsync returns a SecretBundle, of which the most relevant property is the actual value of the secret. Calling SetSecretAsync will create a new version of a secret; this will include creating the secret if it doesn't already exist in your vault, and it will also create a new version even if you set it to the same value as it already holds (GetSecretAsync also has an overload that allows you to specify a version identifier). So putting it all together here's what our console app looks like.

class Program
{
    static string clientId = "myClientId";
    static string clientSecret = "myClientSecret";

    static async Task Main(string[] args)
    {
        KeyVaultClient vaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Program.GetToken));

        string vaultAddress = "https://myVaultUrl";
        string secretName = "secret1";

        var secret = await vaultClient.GetSecretAsync(vaultAddress, secretName);

        Console.WriteLine($"Current secret value: {secret.Value}");

        Console.ReadLine();

    }
            
    private static async Task GetToken(string authority, string resource, string scope)
    {
        ClientCredential credential = new ClientCredential(clientId, clientSecret);

        var context = new AuthenticationContext(authority, TokenCache.DefaultShared);

        var result = await context.AcquireTokenAsync(resource, credential);

        return result.AccessToken;
    }

}
And if I refer back to my vault, you can see that the value of secret1 is indeed 'it's a secret'

So, in this blog we've seen how to create a console application that authenticates against Azure Active Directory and then reads and writes secrets to and from Azure KeyVault. 

I've created a Github repo at https://github.com/philpursglove/KeyVaultDemo with a complete solution for listing, creating, updating and deleting your KeyVault secrets.