Resolved: Removing Claims from ClaimPrincipal in C#

Question:

I am kind of scratching my head to resolve this issue where I have to remove all the Claims in one go. When I use the below code, I get this error Collection was modified; enumeration operation may not execute
Since, I am changing/modifying the value from the enumerator that I am currently looping through, therefore, I am getting this error. Any idea how can I resolve this issue. I have used the below code:
private static readonly string[] claimTypes=
    {
        ClaimTypes.Role,
        ClaimTypes.UserSpecific.IdleSessionTimeout,
        ClaimTypes.CustomerSpecific.ApplicationId,
        ClaimTypes.CustomerSpecific.CustomerId,
        ClaimTypes.CustomerSpecific.CustomerName,
        ClaimTypes.CustomerSpecific.CurrencyCode,
        ClaimTypes.CustomerSpecific.Locale,
        ClaimTypes.CustomerSpecific.TimeZone,
        ClaimTypes.CustomerSpecific.ReportingUnitId
    };


public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
    {
        if (principal == null) throw new ArgumentNullException(nameof(principal));


        foreach (var identity in principal.Identities)
        {
            foreach (var claim in identity.FindAll(claim => claimTypes.Any(type => type == claim.Type)))
            {
                identity.TryRemoveClaim(claim);
            }
        }
    }
Since this was giving error so I thought of using the below code. but this also does not work.
public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
    {
        if (principal == null) throw new ArgumentNullException(nameof(principal));
        var claimNamedList = principal.Identities.Select(x=>x.Claims.Select(y=>y.Type).ToList());
        foreach (var identity in principal.Identities)
        {
            var claimNameList = identity.FindAll(claim => claimTypes.Any(type => type == claim.Type));
            foreach (var name in claimNameList)
            {
                var aa = principal.Identities.Select(x => x.Claims.Where(b => b.Type == name.Type));
                identity.TryRemoveClaim(name);
            }
        }

    }

Answer:

In order to solve this, you need to create a new collection that you enumerate:
public static void RemoveClaimsFor(this ClaimsPrincipal principal, params string[] claimTypes)
{
    if (principal == null) throw new ArgumentNullException(nameof(principal));


    foreach (var identity in principal.Identities)
    {
        var claimsToRemove = identity
          .FindAll(claim => claimTypes.Any(type => type == claim.Type))
          .ToArray();
        foreach (var claim in claimsToRemove)
        {
            identity.TryRemoveClaim(claim);
        }
    }
}
By using ToArray (or ToListor another To* method), the results of the enumeration are stored in a new collection that you can enumerate over. When removing items, this does not affect the newly created collection so the error will be gone.

If you have better answer, please add a comment about this, thank you!

If you like this answer, you can give me a coffee by <a href=”https://violencegloss.com/mkw7pgdwwr?key=2a96ade6f3760c7e63343a320febb78e”>click here</a>

Source: Stackoverflow.com