Skip to content

Add support for ASP.NET (non-Core) projects #2670

Description

@NickCraver

We routinely run into cases where the new project system and ASP.NET MVC 5 collide (or rather, don't) - I'd like to see support added. Here are the main use cases I'm aware of, I hope others add more to this issue:

Use Case: Migration

One of the awesome features of the new .csproj system is glob patterns (and Visual Studio not replacing them on every save). This was something we really looked forward to as a real time saver and merge reducer, but in practice we can't use the new project system because a lot of functionality for ASP.NET MVC 5 apps is missing, e.g. even hitting F5 to run it.

When we migrate a large solution to ASP.NET Core, it's a stop-the-world endeavor as are most major changes. Swapping any fundamental framework piece will need to be a big swap, so you want to reduce that window and risk as much as possible. In the case of ASP.NET to ASP.NET Core, you need to swap the project file, all references, port controllers, views, etc. This is a lot to do at once, and every change since you started that path is a royal pain.

A large part of this pain is in the project file itself, since nearly every commit adding or removing files is a merge conflict. And when moving from non-glob to blog worlds, it's a huge pain to manually sync everything into that major change branch.

But why not just stay on non-globs until after the move?

Again, merge pain. A large change like this necessitates moving files around quite a bit and that's the same merge pain between users as exists in 1 world today.

Use Case: Library Projects

We also have several projects that need to support ASP.NET and ASP.NET Core, there are hundreds of thousands of users on the old systems and we need to support them. In the ASP.NET cases specically, we need to have a ASP.NET and an ASP.NET Core sample. In all of these, the only use of the old project system is the ASP.NET (non-core) sample projects. We have to choose between:

  • Leave it as the old project system, managing both in different ways forever.
  • Screw it, upgrade and host it in IIS, manually attach debuggers, etc.

Adding support for ASP.NET MVC 5 projects for example would help tremendously in porting to ASP.NET Core. In our case, it'd help now for library projects (needed dependencies for main websites to move), and later for those sites like Stack Overflow. We've been working on the .NET Core story for quite a while now, but the daunting task of upgrading the main applications would be made much easier if we could get on the new project system first.

For today examples, I'm using the new .csproj in MiniProfiler and Exceptional MVC 5 Sample projects. The upside is management and simplicity, the downside is users constantly asking why F5 doesn't work. At the moment I'm considering changing them to the old system since the main point of a sample is a bit missed when they can't test it.

Use Case: Immediate

Additionally, it'd just make life easier today in itself, apart from upgrade reasons, by:

  • Eliminating most of the cases we run into merge conflicts today
  • Make git history usable (e.g. when did we upgrade library X?)
  • Reducing project and solution reloads
  • Not restarting Visual Studio constant because of the above (this is still faster than reload in VS 2017)

Can we please consider adding support for these project types? Such support would make life easier both immediately and for upgrading in the future.

Activity

  1. NickCraver commented on Jul 27, 2017

    @NickCraver
    MemberAuthor

    cc @davkean @davidfowl - we've discussed this a bit before as I beat my head on the wall making these things kind-of-work in testing the new system.

  2. mduu commented on Jul 27, 2017

    @mduu

    One more:
    The project files are the files most often result in merge-conflicts because multiple dev added or even renamed files in the projects. Project files are the bottleneck here as most work will result changes in the csproj. Even if the developers work in totally different areas of an assembly chances are high they will get merge conflicts.

  3. xt0rted commented on Jul 27, 2017

    @xt0rted

    I'd love to move my projects over to the new system but I'm forced to stay with MVC5 until all dependencies work on .net core as they do today.

    Since EF code first migrations don't work with the new system the two projects that would benefit from this the most can't be updated (the website & the DAL). Because of this there's nothing to be gained if I migrate the other smaller projects.

    If web projects were supported then one of my two sites could be fully updated, and the other could allow for everything but the DAL project making it worth my time.

  4. mbp commented on Jul 27, 2017

    @mbp

    For the immediate use case, the new project file format provides some great features such as transitive references. And for some reason, updating packages in a large solution with the old project file format takes ages. Just being able to hand-edit the csproj to update version numbers is one of the best features in it.

  5. JesperTreetop commented on Jul 27, 2017

    @JesperTreetop

    As someone with a lot of MVC5 projects, I have considered migrating them to the new csproj, since there's a lot to like. Since NuGet package scripts don't work, this breaks or at least makes working with Entity Framework migrations an unsupported scenario. (See xt0rted's comment.) They are present in all or almost all of the projects I had in mind, so that's a roadblock. Additionally, some NuGet packages that insert themselves into the build process would probably need to be similarly adapted, not to mention any project-type specific tooling (Microsoft or otherwise).

    The features in the new project system would make my life easier - If this could magically be made to work, or if Microsoft would decide to make it a supported scenario and update EF(6) to work (or allow the community to help out), I would consider moving. As an unsupported it-seems-to-work-but-you-break-it-you-bought-it scenario, I wouldn't.

  6. scottsauber commented on Jul 27, 2017

    @scottsauber

    At DevIntersection in May it was said by a MS high up in a session that the new project system was coming to older projects by the end of the year this year, FWIW.

  7. shaggygi commented on Jul 29, 2017

    @shaggygi

    @scottsauber I seriously don't think this will happen based on this Repo Roadmap for milestone 16.

  8. dirething commented on Aug 1, 2017

    @dirething

    I have a number of solutions that contain projects that cannot migrate anytime soon as they rely on things like signalR in its current form, MSMQ and EF code first. It would be nice to be able to start new work where possible in the new system until I have the manpower available to rewrite the main components that rely on things the team has decided not to support in a directly upgradeable manner or does not yet support.

    The library scenario would at least allow some work to begin moving in the right direction here.

  9. added this to the milestone on Sep 4, 2017
  10. NickCraver commented on Sep 30, 2017

    @NickCraver
    MemberAuthor

    Every time we reload the Stack Overflow project (git pull), Visual Studio 2017 crashes. Every single time. Everyone here experiences this, and every time we fix a bug, another pops up later causing the same. While not related directly to this issue, most of the time the project file didn't need to change. Simple support of globs would have prevented the vast majority of reloads in the first place.

    Can we please get an idea of if this will happen? It's the most upvoted issue in this repo and causes tangible daily pain. We want to move to ASP.NET Core, etc. but that's going to take probably a year+. I'm sure there are many, many people in the same boat. Please, add support for the current projects most ASP.NET developers are dealing with and will be for some time.

  11. davidfowl commented on Sep 30, 2017

    @davidfowl
    Member

    Honestly I don't see this happening in the short term (this year). There are lots of kinks to work out with SDK projects and the new project system before we can bring them to older projects. Those kinks don't even have anything to do with ASP.NET so then there would be a bunch of work that needs to happen to port ASP.NET things to the new project system which is non trivial e.g. old razor editor, aspx editor, webforms designer??, build system (WAP projects have a hybrid msbuild + build manager build system), and any other quirks that System.Web requires. Some of those components are written in native code since the older project system was native.

    All of this to say, it's not a simple flip the switch, it's the same set of people working on new and existing project systems. When the SDK projects are near flawless, I'd look at bringing it to down level projects.

  12. NickCraver commented on Oct 1, 2017

    @NickCraver
    MemberAuthor

    @davidfowl I realize to support everything takes more work, but there's a lot of audience covered with far less than all of that. For example out of that entire list only the old razor editor applies to everything we have. But, I'm not sure what's even required there, as the razor editor appears to work as-is. Not listed is F5 debugging, which today results in:

    Unable to run your project. The "RunCommand" property is not defined.

    I am using the new project system for sample applications in our library projects because I have to. You can't mix old and new (see migration issues in the initial post here). It mostly works, but you can't F5 it because it can't launch. The editors work. The build works. Everything we need for daily almost works, if only F5 would start and attach. How much work are we talking about to make that work?

    We don't have webforms, we don't have .aspx, we don't have build issues with WAP, and apps run fine in all our IIS setups (that's how we have to run them on the new project system). That's passable for sample apps (but really, what choice do we have?) but not for a team working together. I guess I disagree on what the minimum bar is here for a huge daily life improvement.

    If F5 worked for spin-up debugging (sometimes attaching isn't practical), we'd have moved over already. What would it take to make this work?

  13. davidfowl commented on Oct 1, 2017

    @davidfowl
    Member

    It might be acceptable for you but I'm like 85% sure we need to have fully parity before claiming that something is a replacement. Those missing features are probably fine for your development but what about other people? Do we replace the default file new or this is just a hacky edit your csproj and hope it works solution for stackoverflow developers?

    If we can't replace the file new project templates for existing ASP.NET 4.x applications then it's not ready yet. You won't believe the sorts of things people rely on Day to day in their projects. Forget those basic features I mentioned, there's also other extensions and features that interact with our project system that would need to work.

    That said we could be making incremental progress but it's not a priority. It needs to work well for .net core projects and it really doesn't as yet. There's lots of performance problems that we're actively working on. To expand the scope of the project system before we worked out some of those major kinks would be a disaster

    It would be awesome if our web project system was OSS so people could contribute and help make this a reality.

  14. NickCraver commented on Oct 1, 2017

    @NickCraver
    MemberAuthor

    @davidfowl We're already in a very hacky state to even think about migrations, anything would be an improvement here. All MS effort appears to be going into a new system we can't realistically migrate to because the old system has been neglected. We have to use VS 2017 for current versions of C#, but to use it with old project systems we're crashing multiple times a day. We can't use VS 2015 unless we want to stick with project.json. We are dedicating our time to libraries on project system in hopes others can use them but we can't even do it ourselves.

    We're stuck in a terrible position here. We can't move to the new stuff that works. Efforts to support the new stuff are quite obviously breaking the old stuff and we're suffering for it with zero benefits. I can honestly say: as things stand, we'd have been better off staying on Visual Studio 2015. Yes, I mean that. But it's too late to go back without significant work, we now use a C# version it doesn't support pervasively.

    There is no incremental migration story. The solution is all or nothing at the moment due to the new project system not supporting all the projects people already have. dotnet msbuild is the same story, since it can build new things but not old projects.

    And let's not forget the clock is ticking. It's already been said that ASP.NET Core 3.0 will drop .NET Framework support and move to .NET Core. This means we have a time limit on an incremental migration story that we can't even begin yet. Due to issues like this migrations to ASP.NET Core remain a logistical nightmare. My teams are asking when we can upgrade and I don't have an answer for them because of these blockers.

  15. 163 remaining items

  16. CZEMacLeod commented on Jan 3, 2025

    @CZEMacLeod

    @NickCraver @davidfowl This is because of the 2 files that are part of Visual Studio that are used as part of the build process for Web Application Projects.
    In my case they resolve to:

    • C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VisualStudio\v17.0\WebApplications\Microsoft.WebApplication.targets
    • C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VisualStudio\v17.0\WebApplications\Microsoft.WebApplication.Build.Tasks.dll

    The problems are
    a) These are part of VS and I don't want to embed them in the SDK as I'm sure they are copyright.
    b) This also pulls in C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VisualStudio\v17.0\Web\Microsoft.Web.Publishing.targets from a similar directory and that has various DLLs too.
    c) These DLLs target NET Framework.

    It does resolve the intial path using $(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets, and I guess I could make it check if the path existed before import, but I don't know exactly how important it is to the build and/or publish process.
    That file resolves the rest using $(AspNetTargetsPath)Microsoft.Web.Publishing.targets

    There was some experimentation done early on in the project trying to use dotnet build CZEMacLeod/MSBuild.SDK.SystemWeb#1 (comment) but it was unsuccessful.

    I know there is a few nuget packages out there which package these files (under the idea of being useful for build servers without the ASP.NET workload installed) - but as I said, I didn't want to include anything copyright / part of VS in the package.

    Example: MSBuild.Microsoft.VisualStudio.Web_WebApplication.Targets although it is a very old version.

    I think part of these targets do the XSD transforms (similar to the slow-cheetah project) that apply the Debug/Release and/or Publish Target web.config transforms.

    With actual input from Microsoft I'm sure all of this could be resolved pretty easily (even the designer hookup stuff could probably be pretty quickly resolved based on enabling for a ProjectCapability). We already added LegacyRazorEditor to make razor work so I'm sure we could get webforms sorted too if there was enough interest.

    Note - I just tried the test from the comment above but with VS2022 installed. As long as you use the latest version of the compilers package etc. (which no longer us CodeTaskFactory) the following works. You can use a BuildTools install instead of the full version. You can set VSToolsPath using the envvars script or VSWhere and then you don't even need to add the property and restore etc. work as expected.

    mkdir test
    cd test
    dotnet new systemwebfull
    dotnet build -p:"VSToolsPath=C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VisualStudio\v17.0"
    Restore complete (0.3s)
    You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
      test succeeded (4.9s) → bin\test.dll
    
    Build succeeded in 5.9s
  17. julealgon commented on Jan 6, 2025

    @julealgon

    show designer / updater designer code files when editing aspx

    This feels like a BIG stretch.

    @davidfowl pretty sure that's not a showstopper though. It's just an annoyance for new development after the conversion.


    In our case, we don't even need the debug and build alone would be a huge win

    We are on the same boat as @NickCraver : just being able to use dotnet CLI against these projects would be absolutely game changing for us as we could then move our entire solution into a much simpler CI/CD pipeline. We are currently maintaining a nasty legacy CI/CD system using Cake that would be completely streamlined if dotnet CLI was an option.

  18. chucker commented on Jan 6, 2025

    @chucker

    pretty sure that's not a showstopper though.

    It's not, for the most part, but I'm a bit surprised/curious. The way we work around this for now is to have an Sdk-style project as well as a classic-style one, and manually keep those in sync if we need to make changes to aspx files that produce changes to designer files.

    I figured what's needed to tell VS to generate the designer files is something like a ProjectCapability or a ProjectTypeGuid.

    Note that I'm not asking for this to work in the .NET Core version of MSBuild, just within an Sdk-style project. As I understand it, when using WindowsDesktop (WinForms, WPF) projects with an Sdk-style project but a 4.x TFM, Visual Studio will automatically use the .NET Framework version of MSBuild; for example, things like SGen and LC are available and work.

  19. objecttothis commented on Jan 28, 2025

    @objecttothis

    We have run into the same problems already reported (designer files not automatically updated, debug doesn't work out of the box, no web forms templates, no intellisense support). I have been manually updating designer files and cloning existing web forms then refactoring. To get debugging to work you can, build, open a page in your web browser (I'm using Firefox Developer Edition) then go to Debug > Attach to Process and select w3wp.exe. It will then start the debugger and I've been able to step through my code as before. On these projects our TargetFramework is net48.

  20. jrmoreno1 commented on Jan 28, 2025

    @jrmoreno1

    @davidfowl :

    A reasonable middle ground might be figure out the work required in tooling to make @CZEMacLeod's MSBuild.SDK.SystemWeb work as well as it can.

    Do you mean mean make it work better (MS employees contributing to @CZEMacLeod 's repo) or pull it into MS? Leaving it where it is with MS contributing would not help many people, pulling it into MS and labeling it experimental or preview, would help a lot more.

  21. NickCraver commented on Jun 12, 2025

    @NickCraver
    MemberAuthor

    In case it helps anyone else, the workaround I'm using given our team is either always in a VS command prompt, building from inside VS (also works), or we init inside the build that command prompt - we lean on that for pathing:

      <!-- Fix VSToolsPath if missing, to allow dotnet build for ASP.NET non-Core web projects. -->
      <PropertyGroup>
        <VSToolsPath Condition="'$(VSToolsPath)' == '' and '$(VSINSTALLDIR)' != '' and Exists('$(VSINSTALLDIR)MSBuild\Microsoft\VisualStudio\v17.0')">$(VSINSTALLDIR)\MSBuild\Microsoft\VisualStudio\v17.0</VSToolsPath>
      </PropertyGroup>

    And this is the part of our PowerShell build script initing the VS prompt from any console in case it helps as well. It looks for a Visual Studio install that has the components (.vsconfig) we need in case of multiple installs (abbreviated for relevancy here)

    $vsconfig = Get-Content ".vsconfig" | ConvertFrom-Json
    $installationPath = & "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -all -requires $vsconfig.components -prerelease -latest -property installationPath
    
    # If we're not in a VS 17 prompt, search for and init the dev prompt environment
    if ($env:VisualStudioVersion -ne "17.0") {
        # Setup this prompt as if it's a VS command prompt by finding the path (vswhere) and copying environment over
        # See: https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt
        $vsDevCmdPath = "$installationPath\Common7\Tools\vsdevcmd.bat"
    
        if (Test-Path $vsDevCmdPath) {
            Write-Host "Visual Studio 17 environment not found, initiaizing from $vsDevCmdPath."
    
            & "${env:COMSPEC}" /s /c "`"$vsDevCmdPath`" -no_logo && set" | ForEach-Object {
                $name, $value = $_ -split '=', 2
                if ($name) {
                    # Note that we get environmental variables from Azure DevOps here that break all kinds of things...ignore those.
                    Set-Content env:\"$name" $value -ErrorAction SilentlyContinue
                }
            }
        }
        Write-Host "MSBuildPath (post-init): $env:MSBuildPath"
    }

    This script is part of our build init script to work from any type of dev console, and overall ensures VSINSTALLDIR is set the same way a VS command prompt would be.

  22. sharpjs commented on Jun 13, 2025

    @sharpjs

    For my use, I've expanded @NickCraver's solution to check the typical install locations if VSINSTALLDIR is not defined. It works for me.

      <!-- Hack to enable web project to build with dotnet.exe -->
      <PropertyGroup>
        <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">17.0</VisualStudioVersion>
        <_VSToolsPathRelative>Microsoft\VisualStudio\v$(VisualStudioVersion)</_VSToolsPathRelative>
        <_WebTargetsPathRelative>WebApplications\Microsoft.WebApplication.targets</_WebTargetsPathRelative>
      </PropertyGroup>
      <PropertyGroup Condition="'$(VSToolsPath)' == '' And '$(VSINSTALLDIR)' != ''">
        <_CandidatePath>$(VSINSTALLDIR)MSBuild\$(_VSToolsPathRelative)</_CandidatePath>
        <VSToolsPath Condition="Exists('$(_CandidatePath)\$(_WebTargetsPathRelative)')">$(_CandidatePath)</VSToolsPath>
      </PropertyGroup>
      <PropertyGroup Condition="'$(VSToolsPath)' == ''">
        <_CandidatePath>$(ProgramFiles)\Microsoft Visual Studio\2022\Enterprise\MSBuild\$(_VSToolsPathRelative)</_CandidatePath>
        <VSToolsPath Condition="Exists('$(_CandidatePath)\$(_WebTargetsPathRelative)')">$(_CandidatePath)</VSToolsPath>
      </PropertyGroup>
      <PropertyGroup Condition="'$(VSToolsPath)' == ''">
        <_CandidatePath>$(ProgramFiles)\Microsoft Visual Studio\2022\Professional\MSBuild\$(_VSToolsPathRelative)</_CandidatePath>
        <VSToolsPath Condition="Exists('$(_CandidatePath)\$(_WebTargetsPathRelative)')">$(_CandidatePath)</VSToolsPath>
      </PropertyGroup>
      <PropertyGroup Condition="'$(VSToolsPath)' == ''">
        <_CandidatePath>$(ProgramFiles)\Microsoft Visual Studio\2022\Community\MSBuild\$(_VSToolsPathRelative)</_CandidatePath>
        <VSToolsPath Condition="Exists('$(_CandidatePath)\$(_WebTargetsPathRelative)')">$(_CandidatePath)</VSToolsPath>
      </PropertyGroup>
      <PropertyGroup Condition="'$(VSToolsPath)' == ''">
        <!-- Unlikely to work from dotnet.exe -->
        <VSToolsPath>$(MSBuildExtensionsPath32)\$(_VSToolsPathRelative)</VSToolsPath>
      </PropertyGroup>
      <PropertyGroup>
        <_VSToolsPathRelative></_VSToolsPathRelative>
        <_WebTargetsPathRelative></_WebTargetsPathRelative>
        <_CandidatePath></_CandidatePath>
      </PropertyGroup>
  23. sharpjs commented on Jun 13, 2025

    @sharpjs

    What does not work from dotnet.exe is view precompile-and-merge.

    First, two missing properties need to be provided — TargetFrameworkSDKToolsDirectory and MSBuildFrameworkToolsRoot — but that is not the roadblock.

    Second, the relevant .targets file invokes an AspNetCompiler task that is a MSBuild built-in. The one in dotnet.exe's MSBuild lacks a ToolPath parameter that the target provides a value for. Even that is not the real roadblock.

    The roadblock is that dotnet.exe's AspNetCompiler task is just a placeholder that emits an error message:

    error MSB4803: The task "AspNetCompiler" is not supported on the .NET Core version of MSBuild. Please use the .NET Framework version of MSBuild. See https://aka.ms/msbuild/MSB4803 for further details.

    I suppose one could provide a UsingTask override or perhaps override the target to do a nested invocation of Visual Studio MSBuild, but both of those sound like more trouble than they're worth.

  24. julealgon commented on Jul 14, 2025

    @julealgon

    This limitation is hitting us hard once again, as we convert our old TeamCity CI/CD pipeline to Github Actions.

    Has there been any progress in here you could share @davidfowl ?

  25. CZEMacLeod commented on Jul 15, 2025

    @CZEMacLeod

    @julealgon I have an example of building with msbuild and running dotnet test on a mixed solution with aspire and asp.net core and non-core (using systemweb-adapters).
    This should cover being able to do all this with github actions.
    https://github.com/CZEMacLeod/C3D.Extensions.Aspire/blob/main/.github/workflows/dotnet-msbuild-vstest.yml
    There is some work been done behind the scenes to try and extract the asp.net webapplication targets from visual studio and make them available by @twsouthwick.
    The big problem is that for webforms, the precompiler is part of netframework and is invoked as a tool. This means you have to use a windows based host/container for compilation, and generally, that you need to use msbuild, either directly or indirectly, with dotnet msbuild instead of dotnet build.
    If you are using MVC, you can partially get round this by using RazorGenerator.MsBuild to build your views into a library.

  26. oleksandrk-adorama commented on Apr 17, 2026

    @oleksandrk-adorama

    Hi everyone,
    As I understand it, after relatively recent changes to the Razor editor dotnet/razor#12332 it's no longer possible to debug Razor views?
    Is this basically the end of the story, with no workable workarounds left?

    Image
  27. CZEMacLeod commented on Apr 17, 2026

    @CZEMacLeod

    @oleksandrk-adorama Not entirely. You can still work with VS2022 instead of VS2026, or roll back to <V18.3 version.
    There are some other rather hacky workarounds but nothing I'm prepared to include in the SDK at this point.

    I am investigating a couple of solutions to this, but haven't made much progress on them yet.

    One is to use the RazorGenerator core as the basis for a sourcegenerator which could mimic the new Razor V4 generator and hopefully integrate that way.

    The other is to have source files mocking the aspnetcore razor libraries which don't get actually built (design time only) which allow breakpoints to be set. The problem with the latter, is that the intellisense etc. then start giving you the new ASPNETCore methods which don't always exactly overlap with the legacy ones.

    If you are doing a cutover with SystemWeb-Adapters you can try something like the following for a razor library that works in both net10/aspnet.core and net48/asp.net mvc5

    <Project Sdk="Microsoft.NET.Sdk">
    
      <Import Project="Sdk.props" Sdk="MSBuild.SDK.SystemWeb.RazorLibrary" Condition="'$(TargetFramework)'=='net48' " />
      <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk.Razor" Condition="'$(TargetFramework)'=='net10.0' " />
    
      <PropertyGroup>
        <TargetFrameworks>net10.0;net48</TargetFrameworks>
        <LangVersion>latest</LangVersion>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <UseRazorSourceGenerator>true</UseRazorSourceGenerator>
        <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
        <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
      </PropertyGroup>
    
      <ItemGroup Condition="'$(TargetFramework)'=='net10.0'">
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
        <AdditionalFiles Include="Views\**\*.cshtml" />
      </ItemGroup>
      <ItemGroup Condition="'$(TargetFramework)'=='net48'">
        <RazorSrcFiles Include="Views\**\*.cshtml" />
        <RazorSrcFiles Remove="Views\_ViewImports.cshtml" />
      </ItemGroup>
    
    
      <Import Project="Sdk.targets" Sdk="MSBuild.SDK.SystemWeb.RazorLibrary" Condition="'$(TargetFramework)'=='net48' " />
      <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk.Razor" Condition="'$(TargetFramework)'=='net10.0' " />
    </Project>
    #if NET48_OR_GREATER
    using System.Web.Mvc;
    using IActionResult = System.Web.Mvc.ActionResult;
    #elif NET10_0_OR_GREATER
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    #endif
    using System.Diagnostics;
    using Microsoft.Extensions.Logging;
    
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> logger;
    
        public HomeController(ILogger<HomeController> logger) => this.logger = logger;
        public IActionResult Index() => View();
    
        public IActionResult Privacy() => View();
    
        [Authorize]
        public IActionResult UserInfo() => View(
    #if NET
            User.Claims
    #else
            (User as ClaimsPrincipal)?.Claims
    #endif
            );
    
    #if NET10_0_OR_GREATER
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    #endif
        public IActionResult Error() => View(new ErrorViewModel { RequestId = Activity.Current?.Id });
    }
    @model IEnumerable<System.Security.Claims.Claim>
    @{
        ViewData["Title"] = "User Info";
    }
    <h1>@ViewData["Title"]</h1>
    
    <h2>@(User.Identity?.Name)</h2>
    <h3>Claims</h3>
    <ul>
    @foreach(var c in Model)
    {
        <li>@c.Type: @c.Value</li>
    }
    </ul>

    You should be able to breakpoint in the views when run from either/both hosts.

  28. oleksandrk-adorama commented on Apr 17, 2026

    @oleksandrk-adorama

    @oleksandrk-adorama Not entirely. You can still work with VS2022 instead of VS2026, or roll back to <V18.3 version. There are some other rather hacky workarounds but nothing I'm prepared to include in the SDK at this point.

    I am investigating a couple of solutions to this, but haven't made much progress on them yet.

    One is to use the RazorGenerator core as the basis for a sourcegenerator which could mimic the new Razor V4 generator and hopefully integrate that way.

    The other is to have source files mocking the aspnetcore razor libraries which don't get actually built (design time only) which allow breakpoints to be set. The problem with the latter, is that the intellisense etc. then start giving you the new ASPNETCore methods which don't always exactly overlap with the legacy ones.

    If you are doing a cutover with SystemWeb-Adapters you can try something like the following for a razor library that works in both net10/aspnet.core and net48/asp.net mvc5

    net10.0;net48 latest enable enable true true true #if NET48_OR_GREATER using System.Web.Mvc; using IActionResult = System.Web.Mvc.ActionResult; #elif NET10_0_OR_GREATER using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; #endif using System.Diagnostics; using Microsoft.Extensions.Logging;

    public class HomeController : Controller
    {
    private readonly ILogger logger;

    public HomeController(ILogger<HomeController> logger) => this.logger = logger;
    public IActionResult Index() => View();
    
    public IActionResult Privacy() => View();
    
    [Authorize]
    public IActionResult UserInfo() => View(
    

    #if NET
    User.Claims
    #else
    (User as ClaimsPrincipal)?.Claims
    #endif
    );

    #if NET10_0_OR_GREATER
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    #endif
    public IActionResult Error() => View(new ErrorViewModel { RequestId = Activity.Current?.Id });
    }
    @model IEnumerable<System.Security.Claims.Claim>
    @{
    ViewData["Title"] = "User Info";
    }

    @viewdata["Title"]

    @(User.Identity?.Name)

    Claims

      @foreach(var c in Model) {
    • @c.Type: @c.Value
    • }
    You should be able to breakpoint in the views when run from either/both hosts.

    @CZEMacLeod Yeah, I understand. Thanks for the reply!
    I'd like to use 2026 because of the AI features, and I also wouldn't want to target .NET 10, so the situation is a bit of a dead end

  29. jrmoreno1 commented on May 13, 2026

    @jrmoreno1

    @davidfowl , @davkean , @NickCraver : given that it's been nearly a decade since this was reported, could any of you confirm who at MS would be working this issue if someone was to work it? Or who would OK the work being done if someone was to do so? This is still an issue, and probably will be for at least another decade if it's not addressed.

  30. davidfowl commented on May 13, 2026

    @davidfowl
    Member

    Nobody is working on this. As for who would be working on it, some combination of the .NET and VS team, but it's not been a priority (relative to other things). My guess is that there's some 80% case you can get working well pretty trivially as @CZEMacLeod has shown, then the last 20% is death by 1000 paper cuts (as this thread is proving).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Parity-Legacy-FeatureMissing features from the legacy project system.Triage-ApprovedReviewed and prioritized

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions