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);
}
}
}
CodePudding user response:
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 ToList
or 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.