简体   繁体   English

Base Controller ASP.NET MVC 3中的此自定义主体效率极低吗?

[英]Is this Custom Principal in Base Controller ASP.NET MVC 3 terribly inefficient?

Despite the fact that I've been on here for a while, this is my first ever question on SO, so please be gentle with me. 尽管我已经来了一段时间,但这是我对SO的第一个问题,因此请对我保持温和。

I'm using ASP.NET MVC 3 and I want to create a custom Principal so I can store a bit more info about the current user than is standard thus not have to go to the database too often. 我使用的是ASP.NET MVC 3 ,我想创建一个自定义的Principal因此我可以存储有关当前用户的信息,而不是标准信息,因此不必经常访问数据库。 It's fairly standard stuff that I'm after. 这是我追求的相当标准的东西。 Let's just say email address and user id in the first instance. 让我们首先说一下电子邮件地址和用户ID。

I have decided to store the object in the cache as I am aware that it is not advised to store it in the session. 我决定将对象存储在缓存中,因为我知道不建议将其存储在会话中。

I also don't want to have to keep casting the User object, so I wanted to override the User object in the controller. 我也不想一直强制转换User对象,因此我想在控制器中覆盖User对象。 So I can just go User.UserId and be guaranteed of something. 因此,我可以只使用User.UserId并得到保证。

So I created a custom principal like this: 所以我创建了一个这样的自定义主体:

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; }
    }
}

And I have a Base Controller like this: 我有一个像这样的基本控制器:

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);
                    }
                }
            }
        }
    }

If you have a look you will quickly realise that if the user has not logged in then any call to the User object will have to run through this bit of code: 如果您看一眼,您会很快意识到,如果用户尚未登录,则对User对象的任何调用都必须通过以下代码来运行:

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

and this feels terribly inefficient to me, although it's only creating empty objects for the missing stuff. 尽管这只是为缺少的内容创建空对象,但是这对我来说却效率极低。

It works fine. 工作正常。

So I guess I want to know if this is actually okay and I should stop being so anal about performance and efficiency, or if my fears are correct, in which case what should I be doing instead? 因此,我想我想知道这是否真的可以,并且我应该不再对性能和效率如此烦恼,或者我的担心是否正确,在这种情况下我应该怎么做? [Please don't say "Getting a life, mate!"] [请不要说:“要命,老兄!”]

No - there is nothing specifically wrong with this code from a performance stand point that stands out. 不-从性能的角度来看,这段代码没有特别的错误。 PLENTY of objects are creating on the back end in ASP.NET, your single object is a drop in the bucket. 在ASP.NET的后端创建了大量对象,您的单个对象简直就是水桶。 Since class instantiation is extremely fast I wouldn't be concerned about it. 由于类实例化非常快,因此我不会在意它。

Why are you ignoring sessions here? 您为什么忽略此处的会话? Session information doesn't have expiration dates, so there is no extra check behind the scenes. 会话信息没有到期日期,因此无需进行任何额外的检查。 Unless you are using an out of proc session server, there is no serialization of your object (none with the cache either). 除非您使用进程外会话服务器,否则不会对您的对象进行序列化(也不会对缓存进行序列化)。 The cache is for every user - so you right a chance (albeit slight) of a code error returning the wrong principal where a cache being per user - does not run the risk of that. 缓存适用于每个用户-因此,您有机会(尽管很小)会遇到代码错误,返回错误的委托人(每个用户都有一个缓存)不会冒这样的风险。

If you want this available for all requests there (not just MVC based) I would consider setting this in Application_PostAuthenticateRequest 如果您希望此功能可用于那里的所有请求(而不仅仅是基于MVC的功能),我会考虑在Application_PostAuthenticateRequest中进行设置

This post may be of use. 这篇文章可能有用。 Notice the use of userdata in the authentication ticket. 请注意,身份验证票证中使用了userdata。

ASP.NET MVC - Set custom IIdentity or IPrincipal ASP.NET MVC-设置自定义IIdentity或IPrincipal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM