It appears I am trying to achieve the impossible: from within a (computed) property of my (entity framework) entity I am trying to check whether the logged on user has a certain claim. To be more precise, it does not work when trying to use this property from within a Linq DB query.
The Linq query is nothing special:
var query = DbContext.Organizations.Where(x => !x.DeleteDate.HasValue);
The data retrieval is triggered by an automapper projection:
var dto = await query.ProjectToListAsync<MyDto>(Mapper.ConfigurationProvider);
I have added this property in my Organization entity:
[Computed]
public bool CanCancel => !CancelDate.HasValue
&& identity.Claims.Any(c => c.Type == permission.ToString()); // identity is of type ClaimsIdentity, permission is an enum from our project
(The Computed attribute comes from the DelegateCompiler library which allows the decompilation of a delegate or a method body to its lambda representation. If you mark a method of your entity with this, Automapper can use it in a query during a projection. We use this technique a lot in our project, it is very useful!)
Unfortunately it does not look like ClaimsIdentity.Claims can be decompiled. Running the code throws the error:
Unable to create a constant value of type 'System.Security.Claims.Claim'. Only primitive types or enumeration types are supported in this context.
I suppose it has something to do with the internals of this Claims property:
public virtual IEnumerable<Claim> Claims
{
get
{
for (int i = 0; i < this.m_instanceClaims.Count; ++i)
yield return this.m_instanceClaims[i];
if (this.m_externalClaims != null)
{
for (int j = 0; j < this.m_externalClaims.Count; ++j)
{
if (this.m_externalClaims[j] != null)
{
foreach (Claim claim in this.m_externalClaims[j])
yield return claim;
}
}
}
}
}
But I fail to see how I could solve this. Does anyone have an idea?
Thanks in advance!