我发现在我的所有操作中都有很多重复的代码,并想知道避免这种情况的最佳方法。比如说每个登录的用户都属于一所学校,我几乎每次都需要访问这个SchoolId。
他们的方式我现在几乎每个动作都会有重复的数据库命中,需要引用我的userService类......类似于:
var claims = new Collection<Claim>
{
new Claim("SchoolId", User.SchoolId.ToString())
};
userIdentity.AddClaims(claims);
我知道我可以将SchoolId添加到声明中,但是在每个方法中返回它的语法都非常冗长(据我所知,这样可以避免每次访问声明时数据库命中?):
在GenerateIdentityAsync中:
var SchoolId = Convert.ToInt32((User as ClaimsPrincipal).Claims.First(x => x.Type == "SchoolId").Value);
在行动中:
from sys import stdin
for line in iter(stdin.readline, "\n"):
# do something
print(line)
这里有什么样的最佳做法吗?可能在声明中将声明存储在全局变量中?
答案 0 :(得分:1)
如何创建自己的控制器,所有控制器继承的控制器都将SchoolId作为属性继承,然后创建一个ActionFilter,将每个控制器转换为该基本控制器并在每个请求上设置该值?然后它将在您的所有操作中可用,但您只需编写一次代码。
它将触发每个请求,因此您可能会考虑使用其他技术来最小化查找值的次数,但此机制是解决代码重复问题的一种方法。
答案 1 :(得分:1)
这就是我在做的......
基本控制器
public class BaseController : Controller
{
public AppUser CurrentUser
{
get
{
return new AppUser(this.User as ClaimsPrincipal);
}
}
}
索赔负责人
public class AppUser : ClaimsPrincipal
{
public AppUser(ClaimsPrincipal principal)
: base(principal)
{
}
public string Name
{
get
{
return this.FindFirst(ClaimTypes.Name).Value;
}
}
public string Email
{
get
{
return this.FindFirst(ClaimTypes.Email).Value;
}
}
}
在另一个控制器中,您只需执行
即可访问声明类型CurrentUser.Email
答案 2 :(得分:0)
我非常喜欢扩展方法方法:
public static int SchoolId(this IPrincipal principal)
{
return Convert.ToInt32((principal as ClaimsPrincipal).Claims.First(x => x.Type == "SchoolId").Value);
}
动作:
var textBooksForSchool = textBookService.GetBooks(User.SchoolId());