这个基本控制器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
- 将模型从一个动作传递到同一控制器中的另一个动作
- 在使用MVCContrib对unit testingMVC 3控制器和视图进行unit testing时,向RouteData添加键和值
- .Replace(Environment.NewLine,“”)适用于localhost但不是我上传网站到主机时
- 如何使CQRS适应项目?
- ASP.NET MVC3将REST服务路由到控制器
- 当用户未在asp.net mvc3中授权时,重定向到另一个页面
- 在ASP.NET中使用Live Connect API检索用户的电子邮件地址
- 如何在ASP.NET MVC 3中为填充的下拉列表创建视图模型
- ASP.NET MVC3代码优先错误 – 尝试更新实体