在基本控制器ASP.NET MVC 3这个自定义用户非常低效? [英] Is this Custom Principal in Base Controller ASP.NET MVC 3 terribly inefficient?

查看:163
本文介绍了在基本控制器ASP.NET MVC 3这个自定义用户非常低效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管我已经在这里一段时间,这是所以我的第一个问题,所以请善待我。

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.

我用 ASP.NET MVC 3 ,我想创建一个自定义主要这样我就可以存储有关当前用户多了一个比特的信息是标准因而不必去到数据库过于频繁。这是说我以后相当标准的东西。远的不说在一审中的电子邮件地址和用户ID。

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. It's fairly standard stuff that I'm after. Let's just say email address and user id in the first instance.

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

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.

我也不想要不断铸造用户对象,所以我想重写用户对象在控制器中。所以,我可以去 User.UserId 和保证的东西。

I also don't want to have to keep casting the User object, so I wanted to override the User object in the controller. So I can just go User.UserId and be guaranteed of something.

因此​​,我创建一个自定义主要是这样的:

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:

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.

它工作正常。

所以我想我想知道这其实是可以的,我应该停止如此肛门有关的性能和效率,或者如果我的恐惧是正确的,在这种情况下应该怎么做呢? [请不要说获取生活,交配!]

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!"]

推荐答案

没有 - 没有什么特别不妥来自脱颖而出性能的立场来看这个code。对象正在创建ASP.NET中的后端鱼米之乡,你的单个对象是杯水车薪。由于类的实例是非常快的,我也不会在意它。

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. Since class instantiation is extremely fast I wouldn't be concerned about it.

你为什么不理会在这里?会话信息没有截止日期,所以在幕后没有任何额外的检查。除非您使用了PROC会话服务器的,没有你的对象序列化(没有与缓存中)。
缓存是对每一位用户 - 所以你权利的code错误的机会(尽管轻微)返回错误主要在哪里缓存为每个用户 - 不运行的,风险

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.

如果你想这适用于所有的请求,这(不只是基于MVC)我会考虑在Application_PostAuthenticateRequest设置此

If you want this available for all requests there (not just MVC based) I would consider setting this in Application_PostAuthenticateRequest

这篇关于在基本控制器ASP.NET MVC 3这个自定义用户非常低效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆