Debugging Enhancements in .NET 8

James Newton-King

Developers love .NET’s powerful and user-friendly debugging experience. Set a breakpoint in your IDE of choice, launch your app with the debugger attached and step through code and see the state of your .NET app.

In .NET 8, we’re investing in improving the debugging experience of commonly used types in .NET apps. These include:

  • HttpContext and friends
  • WebApplication
  • MVC and Razor Pages
  • gRPC
  • Endpoint metadata
  • Logging
  • Configuration

You should be able to find information about your app without having to drill down into the internals of these types. We’ve added debug customization attributes to display debug summaries and provide simplified debug proxies for commonly used .NET types.

HttpContext and friends

HttpContext, HttpRequest and HttpResponse are instantly familiar to developers building web apps with ASP.NET Core. If you want to see the state of an HTTP request, then these are the types that you’d debug.

We’ve reviewed the properties on ASP.NET Core’s HTTP types to make them easy to use with the debugger. Viewing the request and response values, such as headers, cookies, query string, and form values, is much easier. HttpRequest and HttpResponse also now display a user-friendly summary of the type. Essential information like the HTTP request URL or the HTTP response status code is instantly visible.

The screenshot below shows off improvements to HttpContext and associated types:

.NET 7

ASP.NET Core debugging before

.NET 8

ASP.NET Core debugging after

Much better! Although some data is hidden away, nothing is lost. Select Raw View to see all fields and properties.

WebApplication

WebApplication is the default way to configure and start ASP.NET Core apps in Program.cs. WebApplication has been updated to display important information such as configured endpoints, middleware, and IConfiguration values in your IDE’s debugger.

.NET 7

WebApplication debugging before

.NET 8

WebApplication debugging after

We made similar improvements to the .NET Generic Host. The generic host is used to host apps that don’t have HTTP endpoints, such as Unix daemons and Windows Services.

MVC and Razor Pages

ASP.NET Core MVC and Razor Pages are popular frameworks for building web apps. Controllers, views, and Razor Pages receive debugging improvements in .NET 8.

We identified a lot of extra information when debugging these frameworks. Types felt cluttered. In .NET 8, we reviewed each type and asked, “Does this spark joy?”. Most MVC and Razor types now work better with debugging, and non-essential types have been hidden away. The screenshots below show off improvements to MVC’s controller:

.NET 7

Controller debugging before

.NET 8

Controller debugging after

We think you’ll agree this tidied-up output is easier to work with.

gRPC

gRPC is a high-performance library for building RPC services. The latest version of gRPC makes it easier for you to debug gRPC calls from the client. A gRPC call now includes information about its method, status, response headers, and trailers. Additional information about the request/response and streaming depends on the gRPC call type. The example below is a unary call.

grpc-dotnet 2.55.0

gRPC debugging before

grpc-dotnet 2.56.0

gRPC debugging after

Try these changes by updating Grpc.Net.Client to 2.56.0 or later.

Endpoint metadata

Endpoints are a central ASP.NET Core concept. An endpoint represents executable request-handling code. When an app starts up, the endpoints defined in the app are registered with routing. Then, routing matches requests to an endpoint when HTTP requests come into the app. Examples of endpoints include:

  • MVC actions
  • Razor Pages
  • Minimal APIs
  • gRPC methods

Endpoints can have metadata, and metadata controls how the request is executed. For example, an [Authorize] attribute on an API is saved as endpoint metadata, and the AuthorizationMiddleware uses it when processing requests.

In .NET 8, debug text has been added to common metadata. The screenshots below compare debugging Endpoint.Metadata in .NET 7 and .NET 8. It’s easier to understand what metadata has been configured and how requests matched to the endpoint are processed.

.NET 7

Metadata debugging before

.NET 8

Metadata debugging after

Logging

Microsoft.Extensions.Logging is a popular logging library for .NET apps and is used throughout ASP.NET Core. ILogger is used by an app to output structured logs.

ILogger was never designed for debugging. It’s a simple interface for writing logs. That design choice is immediately apparent when debugging an ILogger instance. It displays hard-to-understand data structures that are designed for performance.

In .NET 8, it’s much easier to find out whether logging is enabled and what logging providers have been configured. ILogger displays a user-friendly list of helpful information, such as its name, configured log level, whether it is enabled, and configured logging providers.

.NET 7

Logging debugging before

.NET 8

Logging debugging after

Configuration

Microsoft.Extensions.Configuration is a configuration abstraction used by .NET apps and libraries. IConfiguration can load values from configuration providers, such as JSON files, environment variables, Azure Key Value, or third-party providers.

An example of using configuration is in the ASP.NET Core templates. The appsettings.json file added by templates configures the app’s log levels:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Until .NET 8, figuring out an app’s configuration values could be very difficult. Configuration supports multiple providers, and providers can take precedence over each other. For example, the values in appsettings.json are always used, but they are conditionally overridden by appsettings.Development.json or appsettings.Production.json, depending on how an app is published.

In .NET 8, debugging IConfiguration now displays a simple flat list of all configuration keys and values. Precedence is already calculated, so the configuration values you see are the values the app will use.

.NET 7

Configuration debugging before

.NET 8

Configuration debugging after

And more

There are too many improvements to go into detail for each one. Or even list them. But expect to see many more improvements to debugger visualizations in .NET 8:

  • Dependency Injection
  • ClaimsPrincipal and ClaimsIdentity
  • StringValues and StringSegment
  • HostString, PathString, QueryString and FragmentString
  • HTTP header collections
  • RouteValueDictionary
  • ASP.NET Core MVC’s ModelState

Try it now

.NET 8 debugging enhancements are available now in .NET 8 RC1. Try them today and let us know what you think:

  1. Download the latest .NET 8 release.
  2. Launch Visual Studio 2022 (or your preferred IDE) and create an ASP.NET Core or Worker Service app.
  3. Set breakpoints and hit F5 to run the app with debugging.

Thanks for trying out .NET 8 and .NET 8 debugging enhancements!

25 comments

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

  • Mystery Man 2

    Developers love .NET’s powerful and user-friendly debugging experience.

    Evidence suggests the contrary. .NET 5 and later seem to have a last-mile problem. Windows doesn’t come with modern versions of .NET, let alone use them. Windows 11 still ships .NET Framework 2.0, but not .NET 7. Apparently, the Windows team isn’t comfortable with the latter. The only projects I know to be using modern .NET versions are PowerShell (not the one that ships with Windows), PowerToys, and Paint.net.

    • anonymous 0

      this comment has been deleted.

    • Kenneth Hoff 5

      The fact that Windows does not come preinstalled with every conceivable version of .Net is actually an upside – it’s not sustainable to do so. Because of it, they are actually allowed to change the runtime – imagine that! .Net Framework had an insanely high standard for change, which caused it to stagnate. .Net does not have that limitation, so it’s allowed to progress at a much higher rate!

      That’s not to say that having the runtime preinstalled wasn’t convenient – it certainly was – but the costs outweighed the benefits.

      • Mystery Man 2

        Well, Windows has a performance problem (which .NET can solve) and .NET has an adoption problem (which Windows can solve). If they both manage solve their problems without relying on the other, I’ll keep an open mind. That’s a big “if,” though.

    • Muhammad Miftah 1

      Evidence suggests the contrary. .NET 5 and later seem to have a last-mile problem.
      This response makes no sense – it’s a non-sequitur. A supposed last-mile problem has nothing to do with whether .NET has a user-friendly debugging experience.

    • Nicolas Musset 8

      Nonsense. There is no reason to ship a version of .NET with the OS, given that it will become obsolete very quickly and just clutter the disk. In addition, this would force the .NET team to continue supporting that shipped version during the whole lifecycle of the OS (which is much greater than the release cycle of .NET).

      Separating those two lifecycles was the whole point of the new .NET (Core) to not be tied to a specific version of Windows. Thanks to that separation, the .NET team can move much quicker and release new features following their own schedules.

      • Mystery Man 0

        So, let’s not use innovations because they become obsolete. Instead, let’s stick with what is already obsolete. 🙄

        Remind me again, how long is the lifecycle of the OS these days? Three years, same as .NET LTS. 😮

        Pop quiz. Which one is more cruel: Supporting a good framework for the whole length of an OS lifecycle or developing a framework nobody ever uses? That was not a question. I’ve already heard such bureaucratic nonsense from the Internet Explorer team. They refused to do the right thing because of red tape. Guess what happened? Google Chrome happened. The new Edge team has abandoned all the imaginary red tape, only too late. The same thing is happening to .NET.

        • Johan Visser 3

          Coupling .NET with Windows doesn’t make sense.
          Then they have couple it with Linux, MacOS, Android and any other platform where .NET can run.

        • Michael Taylor 3

          Remind me again, how long is the lifecycle of the OS these days? Three years, same as .NET LTS. 😮

          No, it is at least 10 years, especially for Server. You’re probably referring to the current lifecycle docs here for Windows 10/11. But servers have a lot longer lifecycle for obvious reasons. This is a useful place to find current EOL information. For example Server 2022 has a 10 year lifecycle and Win 11 Home/Pro doesn’t currently list one and we’re 2 years in. Win 10 Ent LTSC lists 6 years.

          So clearly shipping .NET with the OS isn’t a good idea and really never was. If a Windows app needs the framework then it should install the latest version just like everybody else. There are too many non-LTS versions of .NET Core+ to ship them all and assuming the latest version is on any particular OS is a fool’s errand.

          • Mystery Man 0

            Hi. 😊

            .NET is a platform. Being used is its sole purpose. And if the .NET team hasn’t thought about customers with a long-term commitment, it’s high time they did. .NET has had a faithful customer since 2002. You might have heard that customer’s name: Microsoft Windows! That product, however, has been stuck with old and obsolete versions of .NET, namely 2.0, 3.5, and 4.8. The only question is: How do we entice that customer to upgrade to the latest and best .NET version, so that the customer becomes faster and better.

            Fortunately, that customer has never had problems including components with short support periods. For example, it packs Edge, whose support period is five weeks. Historically, it has had such components as DirectX, Internet Explorer, Windows Media Player, and IIS that were updated out-of-band. It’s all thanks to a feature called Windows Update! But if you wish, you can look at it from another angle. Which is easier: Supporting the cranky old 2.0, 3.5, and 4.8 for ten years? Or supporting 8.0 for ten years? The latter. It has better engineering.

      • Tyler 6

        Yes, decoupling .NET from Windows was the entire point. Won’t stop him from posting the same whiny commment in every single article.

    • henry-js 5

      The only projects you know using modern .NET are PowerShell, and yet there are over 99,000 NuGet packages using modern .NET vs 106,000 .NET Framework. DevExpress and SyncFusion both target modern .NET, as do countless other frameworks and libraries, to name a few:
      – Avalonia
      – Uno Platform
      – NewtonSoft.Json
      – NodaTime
      – all the testing libraries
      – Dapper
      – Cake and NUKE
      – NpgSql
      I could go on… Not sure anyone starting a new project would seriously pick Framework over .NET. And the .NET upgrade assistant is surprisingly good from what I’ve heard.
      IMO adoption of modern .NET has been pretty awesome.

      • Mystery Man 2

        These are toolings, not apps. They’re supposed to drive adoption, not represent it.

        Compare .NET’s adoption with the adoption of the Unreal game engine. I can easily list ten big names in gaming developed with Unreal, without including such tooling items as Visual Studio in the list.

        Can you list ten big apps developed in .NET 5 or later?

    • Alfred White 2

      Do people still care about .NET as prerequisite? We ship self-contained deployments of our .NET software so that we don’t have to care what the client has installed. It is WAY better than waiting on windows updates.

      • Michael Taylor 1

        Self contained deployments are useful for some situations but they have some limitations so they aren’t the right solution for a lot of applications.

        Limitation 1 is that you are shipping a subset of the framework for each app. This basically defeats the purpose of having DLLs to begin with. Assuming you only use 1MB of the framework in your app but there are 20 apps that do this then that’s 20MB of space duplicated. Shipping a single copy of the framework eliminates that issue.
        Limitation 2 is security. If your app relies on the shared copy then IT admins (or MS on behalf of the end user) is responsible for ensuring the framework remains patched. With self contained deployments you, the app developer, are responsible for that. Imagine you ship a version of your app with v6.0 of the framework. Then you release a new version of your app using v7.0. Customers may or may not upgrade your app. Suddenly there is a perf/security issue found in the framweork (perhaps related to a recent Windows update). You can easily update your app and push out a new version but customers need to update. Furthermore customers using your older version are still vulnerable as they may be unwilling to upgrade to the newer version of your app. Shared installs don’t have this issue.

        So, yes, sharing framework installations is still criitical and pretty commonplace in my experience.

    • W L 2

      Your same comment under another blog post has already caused many people to participate, so why do you still work tirelessly to start a war under another post.
      I don’t think you want to hear the thinking behind it at all, but just want to see someone supporting you.

    • Robert Gelb 3

      While I agree with you, is it necessary to post this message under every blog post they make?
      And yes, LTS version of .NET Core should be included in Windows. Distributing the entirety of .NET for a sake of a small app is ridiculous.

    • Jorge Morales Vidal 0

      Show your evidence or even better, the studies and articles that support your big claim.

  • Georgi Hadzhigeorgiev 3

    These are great improvements in debugging experience. Thanks!

  • Anuraj Parameswaran 2

    We can’t use .NET 8.0 with Visual Studio 2022, right? We need Visual Studio preview.

    • Michael Taylor 5

      Yes you can use VS 2022, you don’t need the preview. First make sure you have installed the .NET 8 Preview SDK. Then go to VS 2022 -> Tools \ Options -> Environment \ Preview Features and check the box for Use preview of the .NET SDK. Restart VS and then it’ll show up in the list of available frameworks.

      Word of warning however that non-preview versions are older than Preview so some editor features may not work correctly with the latest .NET 8 preview because of changes. But you should be able to compile and run code.

  • Jan Seris 0

    Great job, this looks very nice for quick overviews when hovering over variables when debugging!

  • Johan Visser 5

    The next big think for Microsoft to do is: Port Visual Studio to use .NET 6, 7 or 8

    If they want to promote .NET, they should start using it themselves.

  • Muhamed Karajić 0

    Looks a lot quicker to get the information you would need. Love it!

  • Stefan Fjällemark 0

    A good initiative to clarify data when debugging your application. Previously, you could override ToString() to achieve a similar effect, but with the DebuggerDisplay-attribute you separate the debug display from the more general use of ToString(). I will definitely include this attribute in my own code where it make sense.

    Comment to discussion in this thread
    In my opinion, it is very impolite to destroy the discussion thread with irrelevant posts that do not belong to the topic.

Feedback usabilla icon