12 KiB
ABP Framework 3.3 to 4.0 Migration Guide
This document introduces the breaking changes done in the ABP Framework 4.0 and explains how to fix your 3.x based solutions while upgrading to the ABP Framework 4.0.
See this blog post (TODO: LINK) to learn what's new with the ABP Framework 4.0. This document only focuses on the breaking changes.
Overall
Here, the overall list of the changes;
- Upgraded to the .NET 5.0 (#6118).
- Moved from Newtonsoft.Json to System.Text.Json (#1198).
- Upgraded to the Identity Server 4.1.1 (#4461).
- Switched to
kebab-casefor conventional URLs for the auto API controller routes (#5325). - Removed Retry for the Dynamic HTTP Client Proxies (#6090).
- Creation audit properties of the entities made read-only (#6020).
- Changed type of the IHasExtraProperties.ExtraProperties (#3751).
- Use IBrandingProvider in the Volo.Abp.UI package and remove the one in the Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared (#5375).
- Removed the Angular Account Module Public UI (login, register... pages) since they are not being used in the default (authorization code) flow (#5652).
- Removed the SessionState in the @abp/ng.core package (#5606).
- Made some API revisions & startup template changes for the Blazor UI.
Upgraded to .NET 5.0
ABP Framework has been moved to .NET 5.0. So, if you want to upgrade to the ABP Framework 4.0, you also need to upgrade to .NET 5.0.
See the Migrate from ASP.NET Core 3.1 to 5.0 document to learn how to upgrade your solution to .NET 5.0.
Moved to System.Text.Json
ABP Framework 4.0 uses the System.Text.Json by default as the JSON serialization library. It, actually, using a hybrid approach: Continues to use the Newtonsoft.Json when it needs to use features not supported by the System.Text.Json.
Unsupported Types
If you want to use the Newtonsoft.Json to serialize/deserialize for some specific types, you can configure the AbpSystemTextJsonSerializerOptions in your module's ConfigureServices method.
Example: Use Newtonsoft.Json for MySpecialClass
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.UnsupportedTypes.AddIfNotContains(typeof(MySpecialClass));
});
Always Use the Newtonsoft.Json
If you want to continue to use the Newtonsoft.Json library for all the types, you can set UseHybridSerializer to false in the PreConfigureServices method of your module class:
PreConfigure<AbpJsonOptions>(options =>
{
options.UseHybridSerializer = false;
});
Upgraded to Identity Server 4.1.1
ABP Framework upgrades the IdentityServer4 library from 3.x to 4.1.1 with the ABP Framework version 4.0. IdentityServer 4.x has a lot of changes. Some of them are breaking changes in the data structure.
Entity Changes
Entity changes don't directly affect your application; however, it is good to know.
ApiScope
As the most critical breaking change; Identity Server 4.x defines the ApiScope as an independent aggregate root. Previously, it was the child entity of the ApiResource. This change requires manual operation. See the Database Changes section.
Also, added Enabled(string) and Description(bool,true) properties.
ApiResource
- Added
AllowedAccessTokenSigningAlgorithms (string)andShowInDiscoveryDocument(bool, default: true)properties
Client
- Added
RequireRequestObject <bool>andAllowedIdentityTokenSigningAlgorithms <string>properties. - Changed the default value of
RequireConsentfromtruetofalse. - Changed the default value of
RequirePkcefromfalsetotrue.
DeviceFlowCodes
- Added
SessionId <string>andDescription <string>properties.
PersistedGrant
- Added
SessionId <string>,Description <string>andConsumedTime <DateTime?>properties
Database Changes
Attention: Please backup your database before the migration!
If you are upgrading from 3.x, then there are some steps should be done in your database.
Database Schema Migration
If you are using Entity Framework Core, you need to add a new database migration, using the Add-Migration command, and apply changes to the database. Please review the migration script and read the sections below to understand if it affects your existing data. Otherwise, you may lose some of your configuration, which may not be easy to remember and re-configure.
Seed Code
If you haven't customized the IdentityServerDataSeedContributor and haven't customized the initial data inside the IdentityServer* tables;
- Update
IdentityServerDataSeedContributorclass by comparing to the latest code. You probably only need to add theCreateApiScopesAsyncmethod and the code related to it. - Then you can simply clear all the data in these tables then execute the
DbMigratorapplication to fill it with the new configuration.
Migrating the Configuration Data
If you've customized your IdentityServer configuration in the database or in the seed data, you should understand the changes and upgrade your code/data accordingly. Especially, the following changes will affect your application:
IdentityServerApiScopestable'sEnabledfield is dropped and re-created. So, you need to enable the API scopes again manually.IdentityServerApiResourceScopestable is dropped and recreated. So, you need to backup and move your current data to the new table.IdentityServerIdentityResourceClaimstable is dropped and recreated. So, you need to backup and move your current data to the new table.
You may need to perform additional steps based on how much you made custom configurations.
Other IdentityServer Changes
IdentityServer has removed the public origin option. It was resolving HTTP/HTTPS conversion issues, but they decided to leave this to the developer. This is especially needed if you use a reverse proxy where your external protocol is HTTPS but internal protocol is HTTP.
One simple solution is to add such a middleware at the begingning of your ASP.NET Core pipeline.
app.Use((httpContext, next) =>
{
httpContext.Request.Scheme = "https";
return next();
});
This sample is obtained from the ASP.NET Core documentation. You can use it if you always use HTTPS in all environments.
Related Resources
- https://leastprivilege.com/2020/06/19/announcing-identityserver4-v4-0/
- https://github.com/IdentityServer/IdentityServer4/issues/4592
Auto API Controller Route Changes
The route calculation for the Auto API Controllers is changing with the ABP Framework version 4.0 (#5325). Before v4.0 the route paths were camelCase. After version 4.0, it's changed to kebab-case route paths where it is possible.
A typical auto API before v4.0
camelCase route parts become kebab-case with 4.0
How to Fix?
You may not take any action for the MVC & Blazor UI projects.
For the Angular UI, this change may effect your client UI. If you have used the ABP CLI Service Proxy Generation, you can run the server side and re-generate the service proxies. If you haven't used this tool, you should manually update the related URLs in your application.
If there are other type of clients (e.g. 3rd-party companies) using your APIs, they also need to update the URLs.
Use the v3.x style URLs
If it is hard to change it in your application, you can still to use the version 3.x route strategy, by following one of the approaches;
- Set
UseV3UrlStyletotruein the options of theoptions.ConventionalControllers.Create(...)method. Example:
options.ConventionalControllers
.Create(typeof(BookStoreApplicationModule).Assembly, opts =>
{
opts.UseV3UrlStyle = true;
});
This approach affects only the controllers for the BookStoreApplicationModule.
- Set
UseV3UrlStyletotruefor theAbpConventionalControllerOptionsto set it globally. Example:
Configure<AbpConventionalControllerOptions>(options =>
{
options.UseV3UrlStyle = true;
});
Setting it globally affects all the modules in a modular application.
Removed Retry for the Dynamic HTTP Client Proxies
Dynamic C# HTTP Client Proxies were trying up to 3 times if a request fails using the Polly library. Starting from the version 4.0, this logic has been removed. If you need it, you should configure it in your own application, by configuring the AbpHttpClientBuilderOptions in the PreConfigureServices method of your module.
Example: Retry 3 times on failure by incremental waiting between tries
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientBuildActions.Add((remoteServiceName, clientBuilder) =>
{
clientBuilder.AddTransientHttpErrorPolicy(
policyBuilder => policyBuilder
.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)))
);
});
});
}
This example uses the Microsoft.Extensions.Http.Polly NuGet package.
If you create a new solution, you can find the same configuration in the .HttpApi.Client.ConsoleTestApp project's module class, as an example.
Creation Audit Properties Made Read-Only
Removed setters from the IHasCreationTime.CreationTime, IMustHaveCreator.CreatorId and IMayHaveCreator.CreatorId properties to accidently set the creation properties while updating an existing entity.
Since the ABP Framework automatically sets these properties, you normally don't need to directly set them. If you want to set them, as a best practice, it is suggested to make it in the constructor to not provide a way to change it later.
These properties implemented with protected set in the Entity and AggregateRoot base classes. That means you can still set in a derived class, if you need it. Alternatively, you can use reflection to set them (Or use ObjectHelper.TrySetProperty which internally uses reflection) out of the class if you have to do.
Changed type of the IHasExtraProperties.ExtraProperties
IHasExtraProperties.ExtraProperties was a regular Dictionary<string, object>. With the version 4.0, it is replaced with ExtraPropertyDictionary class which inherits the Dictionary<string, object>.
Most of the applications don't be affected by this change. If you've directly implemented this interface, replace the standard dictionary the the ExtraPropertyDictionary.
ASP.NET Core MVC / Razor Pages UI
See the ASP.NET Core MVC / Razor Pages UI Migration Guide.
Angular UI
See the Angular UI Migration Guide.
Blazor UI
See the Blazor UI Migration Guide.

