March 2nd, 2022

Sharing code between ASP.NET and ASP.NET Core

With the release of .NET 6 there are even more benefits to using ASP.NET Core. But migrating existing code to ASP.NET Core often sounds like a big investment. Today we’ll share how you can accelerate the migration to ASP.NET Core. There are minor changes you can make today that can make it easier to migrate to ASP.NET Core tomorrow.

Before we begin let’s talk about a real scenario. Let’s talk about how to modify code in a 10-year-old application so that it can be shared with ASP.NET Core. In the next sections we’ll give samples that migrate the ShoppingCartController.cs from the MVC Music Store app that was used to demo ASP.NET MVC3.

The first step to migrating this web app is to create a new ASP.NET Core Web App (Model-View-Controller) project. This template will add support for Controllers and map the default route for Controllers in the Program.cs file. Once we have the new project setup, we’ll remove the default HomeController and the view files for Home/Index and Home/Privacy so we can share content from the MVC3 Music Store web app without conflict.

You can share Controllers

The first thing you can share between the two projects is Controllers. Many teams want the new website to work the same as the current one. And when we say “the same” we mean “the same”. If you fix a bug in one project, then you need that same fix to show up in both sites. One of the easiest ways to assure this behavior is to share the same file in both projects. Luckily ASP.NET Core uses the new SDK style project files. That means it’s easy to open the csproj file and add some changes because the files are very readable.

To start sharing a Controller class you’ll need to create an <ItemGroup> and add a reference to the existing class. Here’s a sample that shows how to share the ShoppingCartController.cs by updating the csproj file of the ASP.NET Core project.

    <ItemGroup>
        <Compile Include="..MvcMusicStoreControllersShoppingCartController.cs" LinkBase="Controllers" />
    </ItemGroup>

Okay, now the file is included in the project but you may have guessed that the ASP.NET Core project doesn’t compile anymore. In ASP.NET Core the Controller class doesn’t use System.Web.Mvc it uses Microsoft.AspNetCore.Mvc.

Here’s a sample that shows how the ShoppingCartController.cs can use both namespaces to fix that compiler error.

#if NET
using Microsoft.AspNetCore.Mvc;
#else
using System.Web.Mvc;
#endif

There are other places in the ShoppingCartController that would need to be updated but the approach is the same. Using C# preprocessor directives we can make the class flexible enough to compile for both projects.

For scenarios with large sections of code that work differently for ASP.NET Core you may want to create implementation specific files. A good approach is to create a partial class and extract those code blocks to new method(s) that are different between the two web app targets and use the csproj to control which files are included when building the project.

You can share Models

Now that we can share Controllers we’ll want to share the Models they return. In many scenarios this will just start working when we include them by adding another <ItemGroup> to the csproj file. But if your models also reference System.Web then we can use the same approach we just used for Controllers. Start by updating the namespaces so that the same class file can exist in both projects. Keep using the C# precompiler directives to add ASP.NET Core support.

Here’s a sample that shows how to modify the [Bind] attribute.

#if !NET
    [Bind(Exclude="OrderId")]
#endif
    public partial class Order
    {
        [ScaffoldColumn(false)]
#if NET
    [BindNever]
#endif
        publicintOrderId{ get; set; }
   …
   …

You can share Views

We can even share views. Using the same approach again we can edit the csproj file to share files like the _Layout.cshtml. And, inside the view you can keep using C# precompiler directives to make the file flexible enough to be used by both projects.

Here’s what it looks like to have a master page with mixed support for Child Actions from ASP.NET and View Components from ASP.NET Core so that we can render the part of the page that knows how many items are in the shopping cart.

@{
    #if NET
        <text>@awaitComponent.InvokeAsync("CartSummary")</text>
    #else
        @Html.RenderAction("CartSummary", "ShoppingCart");
    #endif
}

Wrapping up

The ability to share code also includes static content like CSS, JavaScript and images. Step-by-step you can build flexibility into your web app today to make your migration to ASP.NET Core easier.

If you would like more detailed guidance to migrate the entire ShoppingCartController.cs you can follow a full walkthrough with samples at MvcMusicStoreMigration. The walkthrough will also demonstrate how you can run both ASP.NET and ASP.NET Core from the same IIS Application Pool to incrementally migrate your web app one controller at a time.

For those planning to start work on their ASP.NET Core migration we’ll share a few more tips.

  • Upgrade your NuGet packages so you can use netstandard.
  • Change your class libraries to netstandard so you can share code between ASP.NET and ASP.NET Core.
  • Find references to System.Web in your class libraries build interfaces replace them. Use dependency injection so you can easily switch between ASP.NET and ASP.NET Core features.

You can also find more guidance from our docs at Migrate from ASP.NET to ASP.NET Core.

Author

14 comments

Discussion is closed. Login to edit/delete existing comments.

  • Jon Miller

    You should make an article on how to upgrade to Web Forms

  • Patrick Patrick

    Bonjour
    Je développe pour l'instant avec ASPNET j'envisage par la suite de migrer vers ASPNET core.
    Pour l'instant je rencontre le problème de "page blanche" lorsque je veux utiliser les modèles ASPNET Crystal Reporting livrés que ce soit avec Visual Studio professionnel 2019 (dont j'ai acheté une licence) où avec VS2017 community essential . (que ma table fasse partie d'une base Access ou Sqlserver).
    Je ne sais pas où poser cette question ?
    D'avance...

    Read more
  • Rajesh Aravapalli

    Does this solution is good enough to come to Microsoft dev blogs? I am disappointed with this blog post which resembles me shiny title for youtube videos to get views.

  • Jiří Zídek · Edited

    We have done migration of ASP.NET part this way and important things are
    a) ASP.NET is the easiest part in fact and you can keep parallel dev here
    b) I depends how your 10 years-old-app has been "modern" that time, if you used different paradigm how to separate DB/Logic/Server/Presentation parts, it might be unfeasible; for our WebAPI+ReactJS it was not difficult, since we used quite new WebAPI returning directly Poco
    c) For logic part we...

    Read more
  • Keith Jackson

    As with Patrick's comment, I felt I had to write back to this.

    This is awful architectural advice and bad software engineering; I can see a niche use case for this but it adds a level of complexity and complication that you really don't want in your solution.

    I would advise splitting as much code as you can (except controllers) out of your web project, building a new .net Core / .net 6 web project and moving...

    Read more
  • Beau Claar

    This is awesome and all but it's not an issue with CORE or converting that is keeping us from doing it (large enterprise applications). It is LTS timeframe. We have 10 years on a .NET Framework release on an OS but only 3 with a CORE LTS. We have a shop that has a few large applications but hundreds of smaller web applications that do not share similar information to support.

    ...CORE LTS...

    Read more
    • Jorge Morales Vidal

      Maybe your concern is about getting official Microsoft support when things go wrong? As far as I remember, in the old times, getting an issue fixed in the old .NET Framework required waiting for several months or years to get a new update through Windows Update or maybe in a new .NET Framework. With .NET Core, .NET 5 and .NET 6, those fixes now appear in weeks or months at most, and the discussion is...

      Read more
  • Josh H · Edited

    I agree with most of the sentiment of the other comments. It's clear that Microsoft is trying to help us migrate and that is a good thing.

    Since there are obviously detailed steps of known issues and things to watch for... Why not automate all the insertion of the precondions for us automatically? If you can do that so the code can be kept clean, I would be willing to proceed with the other manual steps.

    Read more
  • Mirza Shahzad

    Very nice article but i think there should be more details and code to support this blog post.

    By the way i am using second point from your given tips.

    Change your class libraries to netstandard so you can share code between ASP.NET and ASP.NET Core

    We are using reusable packages that we build in .NET standard 2.0 to support .NET Framework 4.8 and .NET Core 3.1 because our most of the apps are in .NET Framework...

    Read more
  • Morten

    But what if ASP.NET solution is VB?

  • JesperTreetop · Edited

    Include=”..MvcMusicStoreControllersShoppingCartController.cs”

    Looks like WordÑ€ress is being WordÑ€ress once again. This seems to happen on many posts and isn’t very good for things you’re supposed to copy-and-paste.