C# 基本控制器ASP.NET MVC 3中的此自定义主体是否效率极低?

C# 基本控制器ASP.NET MVC 3中的此自定义主体是否效率极低?,c#,performance,asp.net-mvc-3,authentication,iprincipal,C#,Performance,Asp.net Mvc 3,Authentication,Iprincipal,尽管我在这里已经有一段时间了,但这是我第一次问这个问题,所以请对我温柔一点 我使用的是ASP.NET MVC 3,我想创建一个自定义Principal,这样我可以存储比标准更多的关于当前用户的信息,因此不必经常访问数据库。这是我追求的相当标准的东西。让我们先说一下电子邮件地址和用户id 我已决定将对象存储在缓存中,因为我知道不建议将其存储在会话中 我也不想一直强制转换User对象,所以我想覆盖控制器中的User对象。所以我可以去User.UserId并得到一些保证 因此,我创建了一个自定义主体,

尽管我在这里已经有一段时间了,但这是我第一次问这个问题,所以请对我温柔一点

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

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

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

因此,我创建了一个自定义主体,如下所示:

public class MyPrincipal : IPrincipal
{
    public MyPrincipal(IIdentity ident, List<string> 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<string> _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<string>(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);
                    }
                }
            }
        }
    }
这对我来说效率非常低,尽管它只是为丢失的东西创建空对象

它很好用


所以我想我想知道这是否真的是好的,我应该停止对性能和效率如此吹毛求疵,或者如果我的担心是正确的,在这种情况下,我应该怎么做?[请不要说“获得生命,伙计!”

不-从突出的性能角度来看,这段代码没有什么特别的错误。在ASP.NET的后端创建了大量的对象,您的单个对象只是杯水车薪。因为类实例化速度非常快,所以我不关心它

你为什么忽略这里的会话?会话信息没有过期日期,因此在幕后没有额外的检查。除非您使用的是进程外会话服务器,否则不会对对象进行序列化(也不会对缓存进行序列化)。 缓存是针对每个用户的——因此,如果代码错误返回了错误的主体(每个用户都有缓存),那么您纠正了错误的机会(尽管很小)——不会有这种风险


如果您希望所有的请求都可用(不只是基于MVC的),我会考虑在AppultIsPuthAudioTrimeQuest

< P>中设置这个帖子,这篇文章可能有用。请注意在身份验证票证中使用了userdata


别忘了。。。“过早优化是万恶之源。”也就是说,你真的看到性能问题了吗?+1个不错的问题。没有。但问题是,在我看到那一行讨厌的代码之前,我一直觉得自己很聪明,能够让一切正常工作!哇!我真的是肛门!我想这就是开始在BBC Micro上编码的原因,那里的时钟周期很少,而且相差很远……谢谢你。我已经知道如何使用表单身份验证票证,但我想不使用cookie,除非你建议我将其存储在其他地方。+1谢谢Adam。除了安全考虑之外,我没有特别的理由忽略这个会话。我故意没有将其包含在
应用程序\u PostAuthenticateRequest
中,因为我认为其中的代码会针对css、图像、javascript等请求运行,而我的代码不会。是这样吗?任何需要保护的图像都由MVC
FileContentResult
方法提供,因此仍然会被覆盖。
return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty );