ShopifySharp Version 4 Migration Guide

After more than a year of planning and work, ShopifySharp has finally been updated to version 4! There were a ton of improvements and lots of work that went into this release. Chief among the improvements, ShopifySharp version 4 now officially supports building Shopify apps with .NET Core and .NET Standard! (Don't worry, it still supports .NET Framework 4.5 too!)

Other improvements include the ability to finally send partial objects when creating and updating entities (await service.UpdateAsync(id, new Customer() { Phone = "555-555-5555" })), global and instance-specific execution policies (service.SetExecutionPolicy(policy) and ShopifyService.SetGlobalExecutionPolicy(policy)), and every property is now nullable which solves a yuge number of deserialization exceptions that used to break apps in production.

Of course, with every major release comes major breaking changes, and there were a bunch of them in version 4. In fact, those breaking changes are the reason I'm writing this post. After releasing version 4, my focus now is on writing two updates to the Shopify Development Handbook; first to fix the breaking changes that came with ShopifySharp v4, and the second app will be a near-complete rewrite that will cover building Shopify apps with .NET Core!

The purpose of this post, though, is to give you a quick guide to the changes you'll need to make in the current version of the Shopify Development Handbook if you're using ShopifySharp version 4. Unfortunately I failed to mention version pinning the package in the currently released version of the book, so most readers are accidentally installing version 4 of ShopifySharp, instead of version 3.9 that the book was written for.

And that's okay! Version 4 has tons of improvements that I feel make for a better development experience and a better app. So, if you want to continue using version 4 while I work on the updates to the Shopify Development Handbook, here are the changes that you'll need to make to get it working:

Remove the "Shopify" prefix from (almost) everything

We've made things much less verbose in version 4. Where previously every single object and class was prefixed with the world Shopify, almost every single one of those prefixes has been removed.

For example, the ShopifyRecurringCharge object has become RecurringCharge. Similarly, ShopifyAuthorizationService has become AuthorizationService. Hopefully this will save a lot of unnecessary typing, and perhaps spare us from carpal tunnel syndrome. 😉

However, there are two exceptions: the ShopifyException and ShopifyRateException classes both continue to use the "Shopify" prefix, so doing a simple find-and-replace-all is still going to leave some compilation errors.

Request.QueryString and Request.Headers to a list of KeyValuePairs

Several validation and authentication schemes used by Shopify require reading the request's querystring, headers or body. In previous versions of ShopifySharp you could easily pass the Request.QueryString or Request.Headers to their respective AuthorizationService methods. The problem in version 4 is that the NameValueCollection type used by the querystring and headers doesn't technically exist in .NET Standard.

In ShopifySharp v4, the AuthorizationService.IsAuthenticRequest and the ShopifyService.IsAuthenticWebhook methods now expect a list of KeyValuePair<string, StringValues> instead of the NameValueCollection type. To easily convert the querystring and headers to required type, you can copy the following extension method and place it in a folder named "Extensions" in your project directory:

namespace MyNamespace
{
  public static class Extensions
  {
    public List<KeyValuePair<string, StringValues>> ToKvps(this System.Collections.Specialized.NameValueCollection qs)
    {
      Dictionary<string, string> parameters = qs.Keys.Cast<string>().ToDictionary(key => key, value => qs[value]);
      var kvps = new List<KeyValuePair<string, StringValues>>();

      parameters.ToList().ForEach(x =>
      {
        kvps.Add(new KeyValuePair<string, StringValues>(x.Key, new StringValues(x.Value)));
      });

      return kvps;
    }
  }
}

Once you've got that extension method in your project you can easily call Request.QueryString.ToKvps() and Request.Headers.ToKvps() when passing them to AuthorizationService.IsAuthenticRequest and AuthorizationService.IsAuthenticWebhook respectively.

Enums to strings

Finally, the last change you'll need to make is changing a couple of different enums to strings. Almost all enums - excluding the AuthorizationScope enum - were removed in favor of string values. I'm a big fan of using enums liberally in C# projects - they just make things easier - but they caused all kinds of havoc throughout the first two major versions of ShopifySharp.

The problem is that the Shopify API doesn't always document every possible enum value; or they'll occassionally add a new value without announcing it (when they're testing new ones, for example); or the enum will sometimes be null. That's fine if you're running a dynamic language like Ruby or JavaScript, but when you try to deserialize unexpected values in C# you're gonna have a bad time.

Or, more accurately, you're gonna have a deserialization exception. And that's exactly what happened throughout the first two major versions of ShopifySharp before we removed every single enum except for the AuthorizationScope enum. Up until that time, deserialization exceptions were the single most encountered error when using ShopifySharp and easily the most frequent topic in my email inbox.

Now instead of hardcoded enum values, developers like you can quickly update their own apps when values change (or are introduced) and get on with their lives instead of waiting for me to update, test and release a new version of ShopifySharp with the latest values.

With my enum communication liberation in mind, here are the two changes you'll need to make to enums in the currently released version of the Shopify Development Handbook:

  1. The ShopifyChargeStatus.Accepted enum (or ChargeStatus.Accepted enum if you removed the Shopify prefix) must be changed to the string "accepted".
  2. The ShopifyWebhookTopic.AppUninstalled enum must be changed to the string "app/uninstalled".

Beware: both of those strings are case-sensitive!


Those are all of the changes you'll need to make to the guide and samples in the current version of the Shopify Development Handbook. If you've already bought the book then you'll get the next two updates (and every update after that) for free as soon as they're released!

If you haven't had a chance to pick up the book, you can get a free sample chapter right here. Using that free guide, you'll be on your way to building Shopify apps with C# - and soon .NET Core too!


Learn how to build rock solid Shopify apps with C# and ASP.NET!

Did you enjoy this article? I wrote a premium course for C# and ASP.NET developers, and it's all about building rock-solid Shopify apps from day one.

Enter your email here and I'll send you a free sample from The Shopify Development Handbook. It'll help you get started with integrating your users' Shopify stores and charging them with the Shopify billing API.

We won't send you spam. Unsubscribe at any time.