Upgrading to ASP.NET Core 3.1

ASP.NET Core 3.0 and 3.1 brings a lot of changes to the framework, but many of them won't be relevant to your site. Here we'll cover the key changes to update a basic Cofoundry website, but you'll need to read through the Microsoft .NET Core 3.0 and 3.1 migration docs to better understand any additional features that may be affected by the change.

Update your csproj files

In the project file:

  • update the TargetFramework to be netcoreapp3.1
  • remove the Microsoft.AspNetCore.App package
  • update Cofoundry packages and plugins.

A basic project file would look like this after the upgrade:

<Project Sdk="Microsoft.NET.Sdk.Web">


    <PackageReference Include="Cofoundry.Plugins.Imaging.SkiaSharp" Version="0.1.0" />
    <PackageReference Include="Cofoundry.Web.Admin" Version="0.7.0" />


Update program.cs

Next, update your program.cs file to use the new host builder. This is best described in the Microsoft .NET 3.0 migration docs.

Update startup.cs

Cofoundry handles all of the changes required in startup to run Cofoundry, however you may have non-Cofoundry features in your startup that may be affected, so check the migration documentation if you're unsure.

In our basic example, the only two changes to be made are both optional:

  • Optionally change AddMvc to AddControllersWithViews if you aren't using RazoPages. See MVC Service Registration docs for more info.
  • Change IHostingEnvironment to IWebHostEnvironment, as it has been renamed. You may need to add a reference to Microsoft.Extensions.Hosting if you're using the IsDevelopment() extension method.

The basic example is now:

public class Startup
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
        Configuration = configuration;

    public void ConfigureServices(IServiceCollection services)

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        if (!env.IsDevelopment())


Other Breaking Changes

  • IRouteRegistration now accepts an IEndpointRouteBuilder parameters instead of IRouteBuilder in order to support the new endpoint routing features in .NET 3.1.
  • If you're using IEntityFrameworkSqlExecutor, you'll need to udpate references from System.Data.SqlClient to the new Microsoft.Data.SqlClient library.

Notes on compatibility


ASP.NET Core 3 changes the default JSON serlializer from Json.NET to the new System.Text.Json serializer. While the new serializer is faster, it is not as feature rich as Json.NET and so we have reverted the default Json serliazer to Json.NET to resolve compatibility issues.

We will look at reintroducing the new parser when .NET 5 arrives as there should be some new features that make the transition a little smoother.

New SkiaSharp based image resizing package

We're introducing Cofoundry.Plugins.Imaging.SkiaSharp as an alternative imaging solution to Cofoundry.Plugins.Imaging.ImageSharp. The original idea here was to provide a basic no-frills image resizing alternative that uses a permissive licence, however in the last few weeks the ImageSharp team seem to have reverted back to an Apache 2.0 licence for their latest release candidate.

We're still going ahead and releasing the SkiaSharp based plugin and using it as the default choice in the starter templates. The package has the main benefit of not being a pre-release package and having a straight-forward permissive licensing model.

ImageSharp still has a number of benefits over SkiaSharp:

  • Support for a wider range of image formats including (animated) gifs
  • An extensive range of configuration options
  • A much more straight forward and well documented API
  • The ability to preserve EXIF data
  • Fully cross-platform
  • A commercial support model

We'd still recommend using ImageSharp and supporting their excellent library by buying a licence where possible.

Bug fixes

  • #366 Forgot Login Password - Reset Password
  • #347 UI: Page Selector: Ignore leading slash in page search query
  • #363 Unable to edit custom entity without publish permission
  • #339 Publishing pages from page list leaves publish icon greyed out for other pages
  • #370 How to use IOrderableCustomEntityDefinition