Migrating to ASP.NET Core

Serenity has templates for ASP.NET MVC and ASP.NET Core. Even though we kept updating both of them regularly so far, ASP.NET MVC is an obsolete technology which didn't get any new versions for quite a long time.

Microsoft has not released any new version of ASP.NET MVC for years and it is effectively obsolete and is replaced by ASP.NET Core which only runs on .NET Core.

.NET Framework and .NET Core will be merged into .NET 5 soon, which will also unify Mono, Xamarin etc. platforms, which we think is a good idea.

We are also planning to stop releasing new versions of ASP.NET MVC based Serenity templates and NuGet packages soon.

Please perform following steps in order to migrate your Existing Project into ASP.NET Core so that you may keep updating your project.

This document is still a work in progress. You might have to perform some other changes not covered here, depending on the size of your project and any custom code/libraries you have.

Please let us know in Serenity GitHub issues so we update this document accordingly.

We also offer migration services, in case you would like us to migrate your existing project handling any issues thay may arise. Please contact us at support@serenity.is to get a quote.

Existing Project

Update Serenity/StartSharp/Serene to Latest Version for existing project

Backing up existing project

Take a full backup of your solution (ZIP etc) just in case something goes wrong.

Creating Template Project

Renaming Files and Folders

Copying Files from Template Project

Creating and Populating wwwroot folder

Open existing project in Visual Studio.

You may get lots of errors, we'll resolve them one by one.

Replacing namespaces and routes

    [Route("MyModule/MyEntity/[action]")]
    public class MyEntityController : Controller
    {
        // currently this action is only accessible at address MyModule/MyEntity/Index
        // not MyModule/MyEntity unlike ASP.NET MVC, you can't set a default for action parameter
        public ActionResult Index() 
        {
          // ...
        }

        [Route("SomeOther")] // add slash to such route attributes
        // or its address will become MyModule/MyEntity/ActionWithRoute/SomeOther       
        // as route on controller is a prefix for routes on actions
        public ActionResult ActionWithRoute() 
        {
          // ...
        }

        [Route("/Test")] // no change needed for this action as it is rooted
        public ActionResult ActionWithRoute() 
        {
          // ...
        }

        // no change is needed for this action, as it can be accessed at MyModule/MyEntity/ActionNoRoute
        public ActionResult ActionNoRoute()
        {
        }
    }

should become:

    [Route("MyModule/MyEntity/[action]")]
    public class MyEntityController : Controller
    {
        [Route("/MyModule/MyEntity")]
        [Route("/MyModule/MyEntity/Index")] // add this only if you want it to be accessed as /MyModule/MyEntity/Index too
        public ActionResult Index()
        {
          // ..
        }

        [Route("/SomeOther")]
        public ActionResult AnotherAction() {
          // ...
        }

        [Route("/Test")] // no change needed for this action as it is rooted
        public ActionResult ActionWithRoute() 
        {
          // ...
        }

        // no change is needed for this action, as it can be accessed at MyModule/MyEntity/ActionNoRoute
        public ActionResult ActionNoRoute()
        {
        }
    }

In ASP.NET Core there is nothing similar to RoutePrefix attribute, so its not possible to determine Index action as default for a controller route.

If this is too complex, you may also remove route attribute from the controller, and use explicit routes for all actions:

Setting Connection Strings

Open Old.Web.config file and copy connection strings there to appsettings.json under Data.

  "Data": {
    "YourConnectionKey1": {
      "ConnectionString": "YourConnectionString1",
      "ProviderName": "YourProviderName1"
    },
    "YourConnectionKey2": {
      "ConnectionString": "YourConnectionString2",
      "ProviderName": "YourProviderName2"
    }
  },

You may remove Northwind connection in appsettings.json if your existing project doesn't have Northwind connection.

Copying AppSettings

Open Old.Web.config file and copy and extra settings or modified settings you have there to AppSettings section in appsettings.json:

  "AppSettings": {
    "YourJsonSetting1": { 
      // json copied from source replacing single quote with double quote 
    },
    "YourStringSetting2": "value copied from source"
  }

Applying your customizations to tsconfig.json

If you modified tsconfig.json file in your project before migration, make sure you apply similar changes to new tsconfig.json that we copied from template project.

Open Old.tsconfig.json file and tsconfig.json file in your existing project directory and compare them to see if you made any changes that should be transferred to the new one.

If you don't remember doing any manual changes there (which is common for Serenity apps), you may skip this step.

Applying your customizations to package.json

If you modified package.json file in your project before migration, e.g. for adding some packages, make sure you apply similar changes to new package.json that we copied from template project.

Open Old.package.json file and package.json file in your existing project directory and compare them, especially dependencies and devDependencies sections to see if you made any changes that should be transferred to the new one.

If you don't remember doing any manual changes there (which is common for Serenity apps), you may skip this step.

Adding third party package references

If you have any third party package references, other than ones that comes default with StartSharp/Serene, you will need to manually add references to them in your project.

Open Old.packages.config file and identify and extra packages that you might have added to your existing project.

For example if you have a package like below:

<package id="Markdig" version="0.17.0" targetFramework="net461" />

You'll need to first search nuget.org for MarkDig package, determine its latest version (also check if it is compatible with .NET Core/Standard)

Then, edit your project file and add a package reference like following:

<PackageReference Include="Markdig" Version="0.18.1" />

You may also use NuGet package manager to add package references but it might be slower sometimes.

Adding System.DirectoryServices for Active Directory Authentication

If you are planning to use Active Directory Authentication in .NET Core you may have to add following packages:

    <PackageReference Include="System.DirectoryServices" Version="4.7.0" />
    <PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.7.0" />
    <PackageReference Include="System.DirectoryServices.Protocols" Version="4.7.0" />

If you are not going to use AD authentication, you may simply delete User/Authentication/ActiveDirectoryService.cs.

Applying Changes for Code Files with Errors

After doing changes so far, you may still have some errors in a few files like AccountPage.cs, UserRepository.cs etc. These are due to API compatibility problems between .NET Core/Framework and ASP.NET MVC/Core.

You may resolve most of these problems just by copying newer code from template project into existing project for files with compile errors. But if you made manual changes to these files, applying fixes manually could be useful.

Here we list some of manual changes that should be applied to such files if you don't want to copy them from existing project. Please note that these fixes are only valid for current version of Serene/StartSharp and future versions might require applying different changes. So, its a good idea to check most recent code in template project.

Changes in Modules/Membership/Account/AccountPage.cs

If you didn't make any modifications in AccountPage.cs you may directly copy it from template project, otherwise do following changes in AccountPage.cs:

Changes in Modules/Membership/Account/ChangePassword/AccountPage.ChangePassword.cs

If you didn't make any modifications in AccountPage.ChangePassword.cs you may directly copy it from template project, otherwise do following changes in AccountPage.ChangePassword.cs:

Changes in Modules/Membership/Account/ForgotPassword/AccountPage.ForgotPassword.cs

If you didn't make any modifications in AccountPage.ForgotPassword.cs you may directly copy it from template project, otherwise do following changes in AccountPage.ForgotPassword.cs:

Changes in Modules/Membership/Account/ResetPassword/AccountPage.ResetPassword.cs

If you didn't make any modifications in AccountPage.ResetPassword.cs you may directly copy it from template project, otherwise do following changes in AccountPage.ResetPassword.cs:

Changes in Modules/Membership/Account/SignUp/AccountPage.Signup.cs

If you didn't make any modifications in AccountPage.Signup.cs you may directly copy it from template project, otherwise do following changes in AccountPage.Signup.cs:

Changes in Modules/Administration/User/UserListRequest.cs

Copy this file from template project or modify it to add DataProtector property:

    public class UserListRequest : ListRequest
    {
        [JsonIgnore]
        internal IDataProtector DataProtector;
        [JsonIgnore]
        internal byte[] ClientHash;
    }

Changes in Modules/Administration/User/UserEndpoint.cs

Copy this file from template project or apply changes below:

Some of these changes might only be valid for StartSharp

Changes in Modules/Administration/User/UserRepository.cs

Copy this file from template project or apply changes below:

Some of these changes might only be valid for StartSharp

Changes in Modules/Common/Reporting/ReportController.cs

Copy this file from template project or apply changes below:

Changes in Modules/Common/File/FilePage.cs

Copy this file from template project or apply changes below:

Changes in Modules/Common/EmailClient/EmailPage.cs

Copy this file from template project if it exists.

Changes in Modules/Common/EmailClient/EmailEndpoint.cs

Copy this file from template project if it exists.

Changes in Administration/Translation/TranslationRepository.cs

Copy this file from template project or apply changes below:

Changes in Modules/Common/Navigation/NavigationModel.cs

Copy this file from template project or apply changes below:

Changes in Modules/Common/Reporting/ExcelReportGenerator.cs

Copy this file from template project then manually apply your changes if any.

Changes in Modules/Common/Reporting/ReportPage.cshtml

Copy this file from template project then manually apply your changes if any.

Changes in Views/Shared/LeftNavigation.cshtml

Copy this file from template project then manually apply your changes if any.

Changes in Views/Shared/_Layout.cshtml

Changes in Views/Shared/_LayoutNoNavigation.cshtml

Changes in Modules/Membership/Account/AccountLogin.chtml

Applying Your Manual Changes to Startup.cs from SiteInitialization.cs