我正在尝试从HttpContext.User.Claims中提取一个电子邮件地址,我想寻求帮助来想出一个更好的编码方法(也许使用LINQ?)
我现在做这件事的方式似乎很老套。
var userClaimsList = HttpContext.User.Claims.ToList();
// List is of varying length but email is always 3rd from the bottom.
int emailPosition = userClaimsList.Count()-3;
string searchString = "preferred_username: ";
// dirtyEmail = "preferred_username: xyz@emailcom"
string dirtyEmail = userClaimsList[emailPosition].ToString();
string cleanEmail = dirtyEmail.Replace(searchString, "").ToLower().Trim();我已经尝试过LINQ解决方案推荐的in another post,但收到错误Operator == cannot be applied to operands of type 'Claim' and 'string'。
发布于 2018-05-02 01:42:57
声明对象不仅仅是一个简单的字符串,您在userClaimsList中看到的是这些Claim对象的列表。
声明大多是一对claim type和claim value,当您查找有关用户的某些信息时,您应该使用声明类型来标识您正在查找的用户属性。
您在代码中所做的是假设您正在查找的声明是倒数第三个,这本身就是一个危险的假设,因为您不能确定情况是否总是如此:声明通常被认为是无序的,您应该按类型查找它们。一旦获得了类型,就可以对其执行.ToString()操作,这实际上将Claim类型包含的所有信息缩减为claimType: claimValue格式的单个字符串。您可以使用它,但当对象本身作为访问请求值的更好方式时,它的效率确实很低。
由于您正在查找前缀"preferred_username: ",因此我假设preferred_username就是您正在查找的声明类型。在这种情况下,您可以像这样查找该声明:
var claim = HttpContext.User.Claims.First(c => c.Type == "preferred_username");
var emailAddress = claim.Value;如果找不到具有该类型的声明,则使用First将抛出异常。如果你不想这样,你可以使用FirstOrDefault,然后检查claim是否为null。
还有一些助手扩展允许您直接提取声明。在这种情况下,您可以在用户上使用FindFirstValue来直接获取索赔值:
var emailAddress = HttpContext.User.FindFirstValue("preferred_username");如果没有找到该类型的声明,FindFirstValue将返回null,因此在本例中emailAddress可以为null。
发布于 2018-05-02 01:36:07
你所做的不仅是假设一些你不能确保的事情,而且比需要的要难得多:
// note: HttpContext.User == User
var cleanEmail = User.FindFirst(ClaimTypes.Email)?.Value;如果数据不在email声明类型上,请检查相应的类型并改用该类型。在您的例子中,它似乎应该是preferred_username
var cleanEmail = User.FindFirst("preferred_username")?.Value;https://stackoverflow.com/questions/50120968
复制相似问题