I have a UserClaims
table in a SQL DB. The table stores Id
(int), UserId
(int - FK), Type
(nvarchar), and Value
(nvarchar). The Foreign Key maps to the Id
on the User
table. I am currently using Dapper to pull records out of the DB.
When retrieving the UserClaims
for a specific User
, I would like to have the code be "future-proofed" so that, if I add already defined UserClaims
(based on the ClaimTypes
static class in System.Security.Claims
), they will map out and can be referred to elsewhere in the code "natively".
The goal would be to have code like this be functional (obviously this isn't working):
foreach(var c in user.UserClaims)
{
if (!String.IsNullOrEmpty(c.Value) && !String.IsNullOrEmpty(c.Type))
{
if (c.Type == "Role")
authClaims.Add(new Claim(ClaimTypes.Role, c.Value));
else
{
var _type = typeof(ClaimTypes);
var field = _type?.GetField(c.Type);
if (field != null)
authClaims.Add(new Claim(field, c.Value));
else
authClaims.Add(new Claim(c.Type, c.Value));
}
}
}
In the above code, if I can map the Type
coming from the DB to one of the fields in ClaimTypes
, then I want to use that field. If not, then I can create a custom Claim Type that I will need to write some handler for.
Role
was an easy ClaimType
to map, and I could continue that pattern, or possibly implement a switch to map more well-known types, but I was hoping I could leverage the already-existing functionality more cleanly by mapping back to the ClaimTypes
based on their name.
Examples:
authClaims.Add(new Claim(field, c.Value));
// could be equivalent to something like:
authClaims.Add(new Claim(ClaimTypes.Country, "United States"));
// stored in the UserClaims table as:
// 5, 1, 'Country', 'United States' -- OR --
authClaims.Add(new Claim(ClaimTypes.MobilePhone, "+11234567890"));
// 6, 1, 'MobilePhone', '+11234567890'
Try to change your code
var field = _type?.GetField(c.Type);
into
var field = _type?.GetField(c.Type)?.GetValue(null).ToString();
Below is a work demo, you can refer to it:
var UserClaims = new List<UserClaims>() {
new UserClaims() { Type="Country",Value= "United States" },
new UserClaims() { Type="CC",Value= "C1" }
};
var authClaims = new List<Claim>();
foreach (var c in UserClaims)
{
if (!String.IsNullOrEmpty(c.Value) && !String.IsNullOrEmpty(c.Type))
{
var _type = typeof(ClaimTypes);
var field = _type?.GetField(c.Type)?.GetValue(null).ToString();
if (field != null)
authClaims.Add(new Claim(field, c.Value));
else
authClaims.Add(new Claim(c.Type, c.Value));
}
}
result: