---
title: Migrate apps to ASP.NET Core
slug: cms-11/dev-docs/migrating-add-ons-to-net-5
docTags: 
createdAt: 2026-07-22T19:45:22.664Z
---

:::hint{type="info"}
**Note**
See also [Upgrade Assistant](docId\:G_2IGGaI-evR8oFHd6hmv) which is a tool that automates the transition from an ASP.NET Standard project to an ASP.NET Core project.
:::

Microsoft has the following guidelines for migrating to ASP.NET Core: [Overview of porting from .NET Framework to ASP.NET Core](https://docs.microsoft.com/en-us/dotnet/core/porting/).

If your add-on contains views, configure the assembly for precompiled views by changing the SDK type for the project to Razor as `<Project Sdk="Microsoft.NET.Sdk.Razor">`.

You should also add the following property to the `.csproj` file: `<AddRazorSupportForMvc>true</AddRazorSupportForMvc>`.

## Views locations

To avoid collisions in view locations with the partner website, you should store the views for the app (add-on) under a custom folder in the project. If not specified, the default convention is that views are stored under a top folder `<AddonName>.Views`, like this:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/IhlgceXzsBaeRHUlPdOY8-20260722-194646.png "imageqsnmh.png")

You also can specify `viewFolder` in `module.config`, like this: `<module viewFolder="CmsUIViews" ...`.

In that case, the views in the project should look like this:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/JicsZXYGQs1etGhiL0m3z-20260722-194646.png "imagexv0gh.png")

## Precompiled views

A shell module or add-on can have views that are distributed as content together with the module or add-on, and then at runtime, the views are located through an `IFileProvider` (previously `VirtualPathProvider`). You can still have views located and compiled at runtime, but that requires that the application enables the runtime compilation. The modules or add-ons should precompile the views and distribute them in an assembly (typically named `<addon>.Views.dll`) instead.

To avoid the risk of view conflicts with applications or other apps (add-ons), CMS adds, by default, a view location expander that searches for views in `<moduleName>.Views/Views`. You can also use the `viewFolder` attribute in `module.config`.

## Access rights

Previously, a configuration protected shell modules in `web.config` (typically path `/EPiServer`). Instead, each endpoint registered for a shell module is associated with a policy.

You can specify the policy to use for the module through the `authorizationPolicy` attribute in `module.config`. If you do not specify a value for `authorizationPolicy`, a module's endpoints are registered with `ShellModule.DefaultShellModulePolicy`, which requires that the user is part of any of the following roles: **WebEditors**, **WebAdmins**, **CmsAdmins**, or **Administrators**.

## JSON Serialization

In an ASP.NET Core application, a "global" serializer is registered (by default from `System.Text.Json` but you can configure it as NewtonSoft). Use the global serializer for model binding of posted data when you use the `[FromBody]` attribute and when it returns data using OK result, or automatic `IActionResult` conversion.

You should not rely on the global serializer for add-ons or modules because the end application can configure it differently (such as Pascal or camel-casing). You should let each module register its preferred serializer.

If no specific configuration is needed, then it can be specified in `module.config` using the `moduleJsonSerializerType` attribute.

- Enter the **Net** value to specify the built-in serializer in .NET core.
- Enter **Newtonsoft** to use **Newtonsoft.Json**.
- If the module or app requires a custom configuration, then it can set a **None** value and instead call the extension method (to `IServiceCollection`), `UseSystemTextJsonSerialization`, or `UseNewtonsoftSerialization`.

The extension methods let the serializer have a custom configuration. You can register a serializer per assembly and override it per type.
