4

I've got an IClaimsPrincipal variable, and I'd like to see how many claims are in it. Navigating through the properties in the watch window is complicated, so I'd like to customize how this object is displayed.

I'm aware of the [DebuggerTypeProxy] attribute, which initially looked like it might do what I want. Unfortunately, it needs to be attached to the class, and I don't "own" the class. In this case it's a Microsoft.IdentityModel.Claims.ClaimsPrincipal.

I'd like to display the value of IClaimsPrincipal.Identities[0].Claims.Count.

Is there any way, using [DebuggerTypeProxy] or similar, to customize how the value of a type that I don't own is displayed in the watch window?

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380

2 Answers2

5

Example of DebuggerTypeProxyAttribute applied to KeyValuePair showing only the Value member:

using System.Collections.Generic;
using System.Diagnostics;

[assembly: DebuggerTypeProxy(typeof(ConsoleApp2.KeyValuePairDebuggerTypeProxy<,>), Target = typeof(KeyValuePair<,>))]
// alternative format [assembly: DebuggerTypeProxy(typeof(ConsoleApp2.KeyValuePairDebuggerTypeProxy<,>), TargetTypeName = "System.Collections.Generic.KeyValuePair`2")]

namespace ConsoleApp2
{
    class KeyValuePairDebuggerTypeProxy<TKey, TValue>
    {
        private KeyValuePair<TKey, TValue> _keyValuePair; // beeing non-public this member is hidden
        //public TKey Key => _keyValuePair.Key;
        public TValue Value => _keyValuePair.Value;

        public KeyValuePairDebuggerTypeProxy(KeyValuePair<TKey, TValue> keyValuePair)
        {
            _keyValuePair = keyValuePair;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<int, string>() { [1] = "one", [2] = "two" };
            Debugger.Break();
        }
    }
}

enter image description here

Tested on Visual Studio 2017

Jens
  • 2,327
  • 25
  • 34
1

The best I've come up with so far is to call a method:

public static class DebuggerDisplays
{
    public static int ClaimsPrincipal(IClaimsPrincipal claimsPrincipal)
    {
        return claimsPrincipal.Identities[0].Claims.Count;
    }
}

...from the watch window:

DebuggerDisplays.ClaimsPrincipal(_thePrincipal),ac = 10

The ",ac" suppresses the "This expression causes side effects and will not be evaluated".

However, note that when this goes out of scope, Visual Studio will simply grey out the watch window entry, even with the ",ac". To avoid this, you'll need to ensure that everything is fully qualified, which means that you'll end up with extremely long expressions in the watch window.

Community
  • 1
  • 1
Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380