这个基本控制器ASP.NET MVC 3中的自定义主体是非常低效的吗?

尽管我已经在这里待了一段时间,但这是我第一个关于SO的问题,所以请温柔地对待我。

我正在使用ASP.NET MVC 3 ,我想创建一个自定义Principal这样我就可以存储有关当前用户的更多信息而不是标准,因此不必经常访问数据库。 这是我追求的相当标准的东西。 我们先说一下电子邮件地址和用户ID。

我决定将对象存储在缓存中,因为我知道不建议将它存储在会话中。

我也不想继续强制转换User对象,所以我想覆盖控制器中的User对象。 所以我可以去User.UserId并保证一些东西。

所以我创建了一个这样的自定义主体:

 public class MyPrincipal : IPrincipal { public MyPrincipal(IIdentity ident, List roles, string email, Guid userId) { this._identity = ident; this._roles = roles; this._email = email; this._userId = userId; } IIdentity _identity; public IIdentity Identity { get { return _identity; } } private List _roles; public bool IsInRole(string role) { return _roles.Contains(role); } private string _email; public string Email { get { return _email; } } private Guid _userId; public Guid UserId { get { return _userId; } } } 

我有一个像这样的基本控制器:

 public class BaseController : Controller { protected virtual new MyPrincipal User { get { if (base.User is MyPrincipal) { return base.User as MyPrincipal; } else { return new MyPrincipal(base.User.Identity, new List(0), "", Guid.Empty ); } } } protected override void OnAuthorization(AuthorizationContext filterContext) { if (User != null) { if (User.Identity.IsAuthenticated) { if (User.Identity is FormsIdentity) { FormsIdentity id = base.User.Identity as FormsIdentity; MyPrincipal principal = (MyPrincipal)filterContext.HttpContext.Cache.Get(id.Name); if (principal == null) { MembershipUser user = Membership.GetUser(); // Create and populate your Principal object with the needed data and Roles. principal = new MyPrincipal(id, Roles.GetRolesForUser(id.Name).ToList(), user.Email, (Guid)user.ProviderUserKey); filterContext.HttpContext.Cache.Add( id.Name, principal, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new System.TimeSpan(0, 30, 0), System.Web.Caching.CacheItemPriority.Default, null); } filterContext.HttpContext.User = principal; System.Threading.Thread.CurrentPrincipal = principal; base.OnAuthorization(filterContext); } } } } } 

如果您看一下,您将很快意识到,如果用户尚未登录,则对User对象的任何调用都必须通过以下代码运行:

 return new MyPrincipal(base.User.Identity, new List(0), "", Guid.Empty ); 

这对我来说感觉非常低效,虽然它只是为缺少的东西创造空物。

它工作正常。

所以我想我想知道这是否真的好,我应该停止对性能和效率这么肛门,或者如果我的担心是正确的,在这种情况下我应该做什么呢? [请不要说“生活,交配!”]

不 – 从性能观点来看,这个代码没有什么特别的错误。 在ASP.NET的后端创建了大量对象,您的单个对象就是存储桶。 由于类实例化非常快,我不会担心它。

你为什么在这里忽略会议? 会话信息没有到期日期,因此在幕后没有额外的检查。 除非您使用的是一个out of proc会话服务器,否则您的对象没有序列化(也没有缓存)。 缓存适用于每个用户 – 所以你有机会(尽管很轻微)代码错误返回错误的主体,其中每个用户的缓存不会冒这个风险。

如果你希望它可用于所有请求(不仅仅是基于MVC),我会考虑在Application_PostAuthenticateRequest中设置它

这篇文章可能有用。 请注意在身份validation票证中使用userdata。

ASP.NET MVC – 设置自定义IIdentity或IPrincipal