expressappframework-405693-migration-to-net-migration-from-net-framework-in-v-25-2.md
XAF v25.2 ends support for .NET Framework applications (Web Forms and Windows Forms). We removed all .NET Framework modules/APIs and legacy Security System implementations from our source code.
Our focus now is on modern .NET development (ASP.NET Core Blazor, Windows Forms, Web API Service) and on building scalable, multi-tenant/SaaS applications. Migrating from removed modules and APIs to their .NET-based alternatives will help you deliver a better user experience and stronger security. For more information, see the following documents:
Note
For the complete list of removed assemblies, refer to the Removed-XAF-XPO-Assemblies.docx file attached to the following knowledge base article: T1312589 - XAF - Legacy .NET Framework (WinForms and ASP.NET WebForms) APIs, .NET-based API/Modules, and Security System have been removed from distribution.
Follow our migration guidelines:
Note
The legacy Solution Wizard no longer allows you to create new XAF project and item templates. Instead, use the new DevExpress Template Kit that is now automatically added as a Visual Studio extension by our Unified Component Installer.
For more information, refer to the following help topic: Template Kit.
Note
The new Template Kit also supports Rider and VS Code.
We removed the following XAF Windows Forms (.NET) modules, because the Dashboards Module handles many data analytics use-cases much better as we mentioned in the following article: XAF - 2021 Roadmap (Cross-Platform .NET App UI and Security API).
You can also use our standalone WinForms List Editors from the Pivot Grid and Chart modules (PivotGridListEditor and ChartListEditor), as well as their XAF Blazor counterparts.
We removed the following XAF Windows Forms (.NET) modules, because functional/e2e tests with xUnit and C# are easier to implement and maintain (as we first described in 2022).
Note
You can still run and debug .ets files with the TestExecutor utility. We also maintain and improve our EasyTest engine and recommend it to customers (to maintain high quality of their XAF UI-based apps). Internally, we have multiple XAF functional tests, and use xUnit/C#-based functional tests for any new XAF development (instead of .ets files generated by the Script Recorder).
We removed the following EF 6-based packages:
For more information, refer to the following help topics:
XAF v25.2 removes several deprecated security system APIs. Projects that use these old APIs cannot compile after upgrading to v25.2.
Note
For the complete list of removed APIs grouped by assembly, refer to the Removed-Security-API.txt file attached to the following knowledge base article: T1312589 - XAF - Legacy .NET Framework (WinForms and ASP.NET WebForms) APIs, .NET-based API/Modules, and Security System have been removed from distribution.
Migrating your code to new APIs requires manual steps, listed below. We provide a tool to automate some routine tasks and simplify the update, but you will still need to manually modify and review the code.
Important
If your application uses legacy security APIs, update the APIs before upgrading the project to v25.2.
Perform the following steps before you start updating legacy Security APIs:
Complete the steps below if your application uses any of the following legacy classes:
This step creates new tables in your database for users, roles, and permissions in the new format.
Ensure that PermissionPolicyUser, PermissionPolicyRole, SecuritySystemUser, and SecuritySystemRole types are added as exported types.
Add the following code to the SolutionName.Module/DatabaseUpdate/Updater.cs file.
Run your application in debug mode and ensure that the added code is executed.
Note
Run the following SQL query in your database. Note that this query copies data from SecuritySystemUser to PermissionPolicyUser in the MS SQL Server database. If your project uses another database or other user types, change the code to match your data types.
update PermissionPolicyUser
set StoredPassword = (select StoredPassword from SecuritySystemUser where SecuritySystemUser.UserName = PermissionPolicyUser.UserName)
Instead of copying passwords, you can generate new passwords for users. Refer to the following section for more information: Update Legacy User Passwords.
This step is required if your application uses built-in user and role types other than PermissionPolicyUser and PermissionPolicyRole (for instance, SecuritySystemUser / SecuritySystemRole ), or legacy feature toggles: EnableRfc2898, SupportLegacySha512, or AutoAssociationPermissions.
You can use the converter tool to update legacy APIs or update code manually.
Tip
Use a version control system to review changes made by the converter.
We provide a tool to update legacy APIs in your application. You can find the tool source code in the following GitHub repository: XafApiConverter. Compile the XafApiConverter project. Once completed, run the result file from the command line:
XafApiConverter.exe security-update <PathToYourSolution>
<PathToYourSolution> is the full path to your solution. If you specify a folder, the tool processes every solution in the folder and its subfolders.
After the tool finishes, check that your solution compiles and runs. The tool updates deprecated API uses, but it does not ensure that the code compiles or functions correctly afterward. Manual review and additional fixes are necessary if the tool misses something or if issues arise after the update.
Follow these steps to update APIs manually:
Replace old classes with new classes according to the following list.
Update AllowCreate, AllowRead, AllowWrite, AllowDelete, and AllowNavigate properties of the following classes:
Remove usage of ParentRoles and ChildRoles properties from SecuritySystemRole and EF.Role classes. Change user roles and access rights if necessary.
Remove the following feature toggles from your code:
Check that your project compiles and runs.
We have disabled support for legacy password hashing algorithm (LegacySha512) used in applications created before v17.1. XAF applications now use the Rfc2898DeriveBytes API, which implements more secure, FIPS-compliant algorithms.
Important
If your application uses legacy password hashing algorithm, you must update old passwords before you upgrade the project to v25.2.
Your application likely uses legacy algorithm if any of the following conditions apply:
v20_1.PasswordCryptographer.SupportLegacySha512 property is set to true.PasswordCryptographer.EnableRfc2898 property is set to false.You can update outdated passwords in the following ways:
Note
The code samples in this topic use the ApplicationUser type to store user data. If your application uses another type, change the code to match your user type.
These steps force users with outdated passwords to change their passwords when they log in.
Add the following code to the Main method in your project’s Program.cs file to enable both password hashing algorithms:
Ensure that you do not set DefaultSettingsCompatibilityMode to v20_1. Use compatibility mode for a newer version or delete the DefaultSettingsCompatibilityMode setting code.
Add the following code to the UpdateDatabaseAfterUpdateSchema() method in SolutionName.Module\DatabaseUpdate\Updater.cs to execute it during the database update, or to a controller action’s Execute event handler to let the administrator execute it later:
Wait until all users with old passwords update their passwords.
Remove the code you added to the application in the previous steps.
These steps set new administrator-generated passwords for users with outdated passwords. In this case, you do not need to wait until all users update their passwords before upgrading your project.
The application saves the list of users and their new passwords in a text file. The administrator must inform users about their new passwords. Users must change the auto-generated password on their next login.
Add the following code to the Main method in your project’s Program.cs file to enable both password hashing algorithms:
Ensure you do not set DefaultSettingsCompatibilityMode to v20_1. Use compatibility mode for a newer version or delete the DefaultSettingsCompatibilityMode setting code.
Add the following code to the UpdateDatabaseAfterUpdateSchema() method in SolutionName.Module\DatabaseUpdate\Updater.cs to execute it during the database update, or to a controller action’s Execute event handler to let the administrator execute it later:
Run your application in debug mode and ensure that the added code is executed.
Inform users about their new passwords. Users are required to change their passwords when they log in.
Remove the code you added to the application in the previous steps.
You can also use the Reset Password action to change a password for individual users.
Complete these steps if you want to add new authentication methods, such as Microsoft Entra ID. You need to update the user class and database structure.
Tip
If your application uses a user class that inherits from PermissionPolicyUserand implements the ISecurityUserWithLoginInfo interface, you can skip the following steps.
Create an ApplicationUserLoginInfo class. This class must implement the ISecurityUserLoginInfo interface. See the interface documentation for an example.
If your application uses PermissionPolicyUser directly (without a custom descendant), create a descendant class called ApplicationUser. Update your application so it uses this class as the user type.
Implement the ISecurityUserWithLoginInfo interface in your ApplicationUser class. See the interface documentation for an example.
Register ApplicationUserLoginInfo and ApplicationUser as business objects as described in the following topic: Ways to Add a Business Class.
Update your application to use the CreateUser method to create a new user.
Note
To enable new authentication methods, configure your application and authentication providers. The steps in this section prepare your code for future authentication options but do not enable them. Refer to the following help topic for additional information:
WcfSecuredClient, WcfDataServerHelper, MiddleTierSerializableObjectLayerClient, SerializablePermissionRequest, SecuredDataServer, ClientInfo, and so on).Note
For the complete list of removed APIs grouped by assembly, refer to Removed-BaseImpl-Base-DC-API.txt and Removed-DC-API.txt attached to the following knowledge base article: T1312589 - XAF - Legacy .NET Framework (WinForms and ASP.NET WebForms) APIs, .NET-based API/Modules, and Security System have been removed from distribution.
We removed multiple XPO-based demo classes under the DevExpress.Persistent.BaseImpl namespace:
Address, Country, StateOrganization, Party, Person, PhoneNumber, Note, TaskPhoneType, PropertyBag, PropertyBagDescriptor, PropertyDescriptor, PropertyValueDevExpress.Persistent.BaseImpl.Xpo now contains only persistent classes required for the operation of XAF-specific modules (for example, PermissionPolicyUser, ReportData). For more information, refer to the following help topic: Built-in Business Classes & Interfaces.
Our motivation was the same as for the DevExpress.Persistent.BaseImpl.EFCore library in the past. Additionally, we aim to avoid naming and UI/layout conflicts with existing customer classes.
To see the source code of these removed demo classes, download and install v25.1 with the Source & Symbols installer option, and navigate to _c:\Program Files\DevExpress 25.1\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.Xpo_.
The Project Converter automatically removes the DevExpress.ExpressApp.Objects project and code references, so no action is required in most cases. UI and layout settings for built-in persistent classes now ship with DevExpress.Persistent.BaseImpl.Xpo and DevExpress.Persistent.BaseImpl.EFCore packages.
Remove any DCBaseObject mentions and migrate DC interfaces to pure XPO classes.
Remove any mentions of the DistributedIdGeneratorHelper, OidGenerator, and ServerPrefix classes from the DevExpress.Persistent.BaseImpl namespace and follow Auto-Generate Unique Number Sequence instead.
See Also