C#Bot Release


  • Upgraded core framework to .NET 5
    • Incremented all dependencies to their latest versions.
    • With this change the language level for the serverside has increased to C# 9.0 as well as bringing in large performance increases on common code.
    • The process of upgrading to .NET 5 is noted below in the Migration path.
  • Changed to GraphQL data loader for loading references
    • The previous implementation of the GraphQL relations loader would fetch all data in a single SQL query. This will now instead use GraphQL .NET data loaders to load data.
    • This shall significantly increase performance on loading multiple related collections of data.
  • Use Hangfire for scheduled tasks
    • This resolves the limitations of the previous implementation method; a simple hosted service inside of the server.
    • Scheduled tasks are now multinode aware and supports automatic retry of failed jobs.
    • In addition, Hangfire has a built in task dashboard which can be accessed from the admin section of the application or from the /api/hangfire url.


  • Replaced the method of seeding data for API and serverside tests.
    • Now have an API driven method for seeding data.
    • Changed the API and Selenium test frameworks to no longer access the server DLL and reference code in the server.
  • Added server health endpoint at /api/health
  • Added bot version to the admin dashboard of the client-side.
  • Add ability for textbox to set fields to undefined if the text box is emptied.
  • The CrudService will now resolve a new DbContext instance for each function call
    • This is instead of resolving the scoped context.
    • This will mean that calls to this service can no longer pollute the change tracker of the scoped context.

Resolved defects

  • Fixed issue with test super user not having access to certain admin pages if there were no other user types in the application.
  • Models on the client-side will now parse created and modified dates as UTC.
  • Fixed collection reference graphql resolvers not applying conditions.
  • Fixed assignAttributes function on client-side models not being able to set falsy values.
  • Fixed IQueryable extension methods throwing on being provided null arguments.
    • These will now continue with no action performed instead.
  • IdentityService.RetrieveUserAsync will no longer throw an exception if called outside the scope of a HTTP request.
  • ASP.NET Authentication will now correctly using the cookies authentication scheme as its default fallback and authenticate scheme and the JWT scheme as the default challenge scheme.
  • Fixed server-side tests using incorrect claims for authenticating users.
  • Fixed incorrect assertion on security tests.

Migration Path

.NET 5

With the upgrade to .NET 5 from .NET Core 3.1 you will need to update your development and server environments to use the latest SDK and runtime. The latest .NET 5 SDK and runtime can be downloaded from here.

Database changes

In the process of updating to Entity Framework 5, the method for database inheritance has been changed. In versions up to of C#Bot there was table annotations on all tables, causing issues with the changes to the inheritance model due to users not existing in their own table. To address this issue a hotfix version was released that removes these annotation from user entities.

To avoid any complications with corrupted migrations perform the following changes.

  • Update to version of C#Bot.
  • Create a new migration on this version by running dotnet ef migrations add FixUsers and commit it to the git repository. This migration should be blank however it will alter the database snapshot file.
  • Upgrade bot version to

Misc changes

  • GraphQL resolvers previously received a ResolveFieldContext from the GraphQL.Types namespace. With the new version of the GraphQL library the resolvers will now receive a IResolveFieldContext from the GraphQL namespace. These classes both contain the same fields, so this should only break definitions.
  • The server builder in both the server-side and server-side tests will now return an IHost from the Microsoft.Extensions.Hosting namespace instead of an IWebHost from Microsoft.AspNetCore. All code that references the old class directly will need to be updated and the new namespace will need to be imported.
  • With the update to a data loader implementation of the GraphQL navigation fields the GraphQL entity types now no longer inherit from EfObjectGraphType and now instead inherit from ObjectGraphType. Any custom relations that relied on the methods on this class should be updated to use a data loader implementation instead.

Scheduled task changes

There has been large structural changes with the functionality of the scheduled tasks. Previously, to create a scheduled task you would create a new class that implements the IScheduledTask interface, create a public Schedule on it to store the cron timer and an ExecuteAsync method for the runtime logic. With the new rewrite of scheduled tasks the IScheduledTask interface has been removed and the declaration of the cron timer has been moved into the task registration. To update perform the following steps

  • Remove the IScheduledTask declaration from your task class
  • Remove the Schedule field from the task class
  • In Startup.cs in the ‘Add methods before data seeding here’ protected region add the following code
// % protected region % [Add methods before data seeding here] on begin
// First parameter is a unique id for the task
// Second parameter is the function to run on this class.
// Third parameter is the Cron timer to run on.
RecurringJob.AddOrUpdate<TankManagementTask>("Tank Task", task => task.ExecuteAsync(), "0 7 * * *");
// % protected region % [Add methods before data seeding here] end

As part of the upgrade to use Hangfire for scheduled tasks in their default form, a database migration is required to add the appropriate tables. This can be done by running dotnet ef migrations add AdHangFire and running and committing that to the repository.

For more information see the Hangfire Documentation.

Test changes

With the update to the API and Selenium tests not having access to the database, this could break some tests that depended on the functionality. For any API tests that have been broken it is recommended to convert these to server-side tests instead. In the case that you need to use the servers Postgres database in a test instead of the in memory testing database, you can configure your server as follows when building it.

var host = ServerBuilder.CreateServer(new ServerBuilderOptions
	DatabaseOptions = (options, context) =>
		return builder =>

Protected region changes

File Old Name New Name/Change Reason
FileController.cs Add any extra get arguments here Add any extra metadata arguments here This protected region had a duplicate name which has now been fixed.
CountQuery.cs Override CreateConditionalCountQuery here Removed The function this was wrapping no longer exists.
Schema.cs Override connection query here Removed The function this was wrapping no longer exists.
Program.cs Change Startup to custom Startup class here Contents Changed The contents of this protected region has changed to support the new style host builder.
Startup.cs Add more scheduled task here Configure scheduled task library here With the complete refactor of scheduled tasks this region was changed as the functionality is completely different