Asp.net mvc MVC.Net-缓存用户对象以为应用程序提供数据(请求汇总)

Asp.net mvc MVC.Net-缓存用户对象以为应用程序提供数据(请求汇总),asp.net-mvc,session,caching,mvcsitemapprovider,Asp.net Mvc,Session,Caching,Mvcsitemapprovider,我真的很感激一些建议,以帮助我与对象缓存。 这是我的需要:我想根据存储在SQL数据库中的用户角色过滤控制器的一些操作 我现在要做的是:当当前用户的第一个请求完成时,我生成一个对象,其中包含一些由SQL查询初始化的属性。我使用自定义提供程序将此对象存储到会话中,并使用自定义角色提供程序处理授权筛选器标记。如果会话过期,则重新生成用户。。是这样的(简化): 用户类 Public class User public property Login as string public prop

我真的很感激一些建议,以帮助我与对象缓存。 这是我的需要:我想根据存储在SQL数据库中的用户角色过滤控制器的一些操作

我现在要做的是:当当前用户的第一个请求完成时,我生成一个对象,其中包含一些由SQL查询初始化的属性。我使用自定义提供程序将此对象存储到会话中,并使用自定义角色提供程序处理授权筛选器标记。如果会话过期,则重新生成用户。。是这样的(简化):

用户类

Public class User

   public property Login as string
   public property IsAdmin as boolean

   public sub Init(byval pLogin as string)
        Login = pLogin
        //Do some logic on database to provides roles....
        IsAdmin = dbReturnIsAdmin
   end sub

   public readonly property RolesList as string()
       Get
          Return New String() {If(IsAdmin, "UserIsAdmin", "")}
       End get
   end property 

End class
会话用户提供程序

Public Class SessionProvider

   Private Const SESSION_USER As String = "SESSION_USER"

    Public Shared Sub ReloadUser()
        //'This instruction initiate user and load roles into an User class type object
        HttpContext.Current.Session(SESSION_USER) = StructureService.GetInitializedUser(My.User.Name, UowProvider.StructureUow)
    End Sub

    Public Shared ReadOnly Property User() As Application.User
        Get
            //'If user doesn't exist so we create an user

            If HttpContext.Current.Session(SESSION_USER) Is Nothing Then ReloadUser()

            //'Return user
            Return CType(HttpContext.Current.Session(SESSION_USER), Application.User)
        End Get
    End Property

End Class
Public Class AuthentifiedRoleProvider
    Inherits RoleProvider
    //Implement base role provider....

    Public Overrides Function GetRolesForUser(username As String) As String()
        return SessionProvider.User.RolesList
    End Function

End Class
    <Authorize(Roles:="UserIsAdmin")>
    Public Function List_Items() As ActionResult
        Return View()
    End Function
   Public Class UserProvider


    Private Const USER_CACHE_PREFIX As String = "User|"

    Private Shared Sub AddUserToCache(ByVal pLogin As String, ByVal pUser As Application.User)
        Dim objCache As ObjectCache = MemoryCache.Default
        objCache.Add(USER_CACHE_PREFIX & pLogin, pUser, New CacheItemPolicy With {.SlidingExpiration = TimeSpan.FromSeconds(20)})
    End Sub

    Private Shared Function GetUserFromCache(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        //Return cache if exists
        If objCache.Contains(USER_CACHE_PREFIX & pLogin) Then
            Return CType(objCache.GetCacheItem(USER_CACHE_PREFIX & pLogin).Value, Application.User)
        Else
            Return Nothing
        End If
    End Function

    Public Shared Function ReloadUser(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        Dim tmpLogin As String = My.User.Name
        //Clear cache
        If objCache.Contains(USER_CACHE_PREFIX & tmpLogin) Then objCache.Remove(USER_CACHE_PREFIX & pLogin)
        Dim tmpUser As Application.User = StructureService.GetInitializedUser(pLogin, UowProvider.StructureUow) 
        AddUserToCache(tmpLogin, tmpUser)
        return tmpUser
    End Function

    Public Shared ReadOnly Property User() As Application.User
        Get
            Dim tmpLogin As String = My.User.Name
            //Try to get user from cache
            Dim tmpUser As Application.User = GetUserFromCache(tmpLogin)
            //If user is null then init and cache
            If tmpUser Is Nothing Then
                tmpUser = StructureService.GetInitializedUser(tmpLogin, UowProvider.StructureUow) 
                AddUserToCache(tmpLogin, tmpUser)

            End If

            //return  user
            Return tmpUser
        End Get
    End Property

End Class
自定义角色提供程序

Public Class SessionProvider

   Private Const SESSION_USER As String = "SESSION_USER"

    Public Shared Sub ReloadUser()
        //'This instruction initiate user and load roles into an User class type object
        HttpContext.Current.Session(SESSION_USER) = StructureService.GetInitializedUser(My.User.Name, UowProvider.StructureUow)
    End Sub

    Public Shared ReadOnly Property User() As Application.User
        Get
            //'If user doesn't exist so we create an user

            If HttpContext.Current.Session(SESSION_USER) Is Nothing Then ReloadUser()

            //'Return user
            Return CType(HttpContext.Current.Session(SESSION_USER), Application.User)
        End Get
    End Property

End Class
Public Class AuthentifiedRoleProvider
    Inherits RoleProvider
    //Implement base role provider....

    Public Overrides Function GetRolesForUser(username As String) As String()
        return SessionProvider.User.RolesList
    End Function

End Class
    <Authorize(Roles:="UserIsAdmin")>
    Public Function List_Items() As ActionResult
        Return View()
    End Function
   Public Class UserProvider


    Private Const USER_CACHE_PREFIX As String = "User|"

    Private Shared Sub AddUserToCache(ByVal pLogin As String, ByVal pUser As Application.User)
        Dim objCache As ObjectCache = MemoryCache.Default
        objCache.Add(USER_CACHE_PREFIX & pLogin, pUser, New CacheItemPolicy With {.SlidingExpiration = TimeSpan.FromSeconds(20)})
    End Sub

    Private Shared Function GetUserFromCache(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        //Return cache if exists
        If objCache.Contains(USER_CACHE_PREFIX & pLogin) Then
            Return CType(objCache.GetCacheItem(USER_CACHE_PREFIX & pLogin).Value, Application.User)
        Else
            Return Nothing
        End If
    End Function

    Public Shared Function ReloadUser(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        Dim tmpLogin As String = My.User.Name
        //Clear cache
        If objCache.Contains(USER_CACHE_PREFIX & tmpLogin) Then objCache.Remove(USER_CACHE_PREFIX & pLogin)
        Dim tmpUser As Application.User = StructureService.GetInitializedUser(pLogin, UowProvider.StructureUow) 
        AddUserToCache(tmpLogin, tmpUser)
        return tmpUser
    End Function

    Public Shared ReadOnly Property User() As Application.User
        Get
            Dim tmpLogin As String = My.User.Name
            //Try to get user from cache
            Dim tmpUser As Application.User = GetUserFromCache(tmpLogin)
            //If user is null then init and cache
            If tmpUser Is Nothing Then
                tmpUser = StructureService.GetInitializedUser(tmpLogin, UowProvider.StructureUow) 
                AddUserToCache(tmpLogin, tmpUser)

            End If

            //return  user
            Return tmpUser
        End Get
    End Property

End Class
实施-网络配置

    <system.web> .....
     <roleManager cacheRolesInCookie="false" defaultProvider="DefaultRoleProvider" enabled="true">
         <providers>
             <clear />
             <add name="DefaultRoleProvider" type="AuthentifiedRoleProvider" />
         </providers>
     </roleManager>     
   </system.web>
。。。。。
实施-控制器

Public Class SessionProvider

   Private Const SESSION_USER As String = "SESSION_USER"

    Public Shared Sub ReloadUser()
        //'This instruction initiate user and load roles into an User class type object
        HttpContext.Current.Session(SESSION_USER) = StructureService.GetInitializedUser(My.User.Name, UowProvider.StructureUow)
    End Sub

    Public Shared ReadOnly Property User() As Application.User
        Get
            //'If user doesn't exist so we create an user

            If HttpContext.Current.Session(SESSION_USER) Is Nothing Then ReloadUser()

            //'Return user
            Return CType(HttpContext.Current.Session(SESSION_USER), Application.User)
        End Get
    End Property

End Class
Public Class AuthentifiedRoleProvider
    Inherits RoleProvider
    //Implement base role provider....

    Public Overrides Function GetRolesForUser(username As String) As String()
        return SessionProvider.User.RolesList
    End Function

End Class
    <Authorize(Roles:="UserIsAdmin")>
    Public Function List_Items() As ActionResult
        Return View()
    End Function
   Public Class UserProvider


    Private Const USER_CACHE_PREFIX As String = "User|"

    Private Shared Sub AddUserToCache(ByVal pLogin As String, ByVal pUser As Application.User)
        Dim objCache As ObjectCache = MemoryCache.Default
        objCache.Add(USER_CACHE_PREFIX & pLogin, pUser, New CacheItemPolicy With {.SlidingExpiration = TimeSpan.FromSeconds(20)})
    End Sub

    Private Shared Function GetUserFromCache(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        //Return cache if exists
        If objCache.Contains(USER_CACHE_PREFIX & pLogin) Then
            Return CType(objCache.GetCacheItem(USER_CACHE_PREFIX & pLogin).Value, Application.User)
        Else
            Return Nothing
        End If
    End Function

    Public Shared Function ReloadUser(ByVal pLogin As String) As Application.User
        Dim objCache As ObjectCache = MemoryCache.Default
        Dim tmpLogin As String = My.User.Name
        //Clear cache
        If objCache.Contains(USER_CACHE_PREFIX & tmpLogin) Then objCache.Remove(USER_CACHE_PREFIX & pLogin)
        Dim tmpUser As Application.User = StructureService.GetInitializedUser(pLogin, UowProvider.StructureUow) 
        AddUserToCache(tmpLogin, tmpUser)
        return tmpUser
    End Function

    Public Shared ReadOnly Property User() As Application.User
        Get
            Dim tmpLogin As String = My.User.Name
            //Try to get user from cache
            Dim tmpUser As Application.User = GetUserFromCache(tmpLogin)
            //If user is null then init and cache
            If tmpUser Is Nothing Then
                tmpUser = StructureService.GetInitializedUser(tmpLogin, UowProvider.StructureUow) 
                AddUserToCache(tmpLogin, tmpUser)

            End If

            //return  user
            Return tmpUser
        End Get
    End Property

End Class

公共函数列表_项()作为ActionResult
返回视图()
端函数
它正在工作

但是,我想知道这是否真的是实现这一目标的好方法。 由于我的应用程序上有一个指向控制器操作的站点地图,sessionprovider用户(顺便说一句,还有http会话)会被请求4到5次每次菜单加载

因此,我的问题是:

  • 存储到会话是否会带来性能问题
  • 有没有更好的方法将我的用户对象存储到一种缓存中(->我认为是system.runtime.cache)
  • 不管怎样,你认为这个实施对实现我的目标有好处吗
非常感谢

不管怎样,你认为这个实施对实现我的目标有好处吗

可能不会

  • 出于某种原因,您正在将会话状态绑定到用户配置文件数据。会话状态与授权/身份验证无关,因为使用会话状态(在任何实际意义上)意味着您的应用程序每个HTTP请求将需要2个额外的网络请求。此外,无论用户是否登录,这些额外请求都会发生
  • MvcSiteMapProvider
    不依赖于会话状态。它使用共享缓存将节点存储在RAM中,并使用
    AuthorizeAttribute
    确定每个请求显示/隐藏哪些节点
  • 如果发现每个请求都多次请求相同的数据,则应尝试使用与以下类似的标准缓存检索模式利用请求缓存(
    HttpContextBase.Items
    ):

    Public Function GetSomeData() As ISomeData
        Dim key As String = "SomeDataKey"
        ' Me.cache refers to HttpContextBase.Items injected through 
        ' the constructor of this class and stored in a private field
        Dim someData As ISomeData = TryCast(Me.cache(key), ISomeData) 
        If someData Is Nothing Then
            ' The data is not cached, so look it up and populate the cache
            someData = GetDataFromExternalSource()
            Me.cache(key) = someData
        End If
        Return someData
    End Function
    
    将这样的方法放入组件之间共享的服务中意味着您不必担心在请求中多次检索相同的数据——第一次访问外部源时,以及每增加一次使用缓存时

    此外,根据:

    创建自定义角色提供程序有两个主要原因

  • 您需要将角色信息存储在.NET Framework中包含的角色提供程序不支持的数据源中,例如FoxPro数据库、Oracle数据库或其他数据源
  • 您需要使用与.NET Framework附带的提供程序使用的数据库架构不同的数据库架构来管理角色信息。一个常见的例子是公司或网站的SQL Server数据库中已经存在的角色数据
  • 因此,如果你没有做这两件事,那也可能不是正确的选择。大多数现代应用程序都可以使用/扩展进行用户身份验证,所有MVC应用程序都应该使用(或其子类)进行授权

    System.Runtime.Cache.ObjectCache
    (和
    MemoryCache
    )是缓存用户之间通常不共享的数据的好方法。如果将缓存密钥设计为包含用户的唯一标识符以及使该密钥唯一的分隔符,则可以将其用于用户数据

    Dim key As String = UserId & "|UserProfile"
    
    也就是说,您应该知道,这种缓存方式不会扩展到多个服务器


    不管怎样,我建议你在工作中遵循建议。MVC使我们在许多情况下不必使用会话状态,除非绝对需要,否则我们不应该使用它。

    多亏了建议,我将会话用户提供程序改为使用缓存。它必须延长,但现在我可以看到变化

    会话用户提供程序

    Public Class SessionProvider
    
       Private Const SESSION_USER As String = "SESSION_USER"
    
        Public Shared Sub ReloadUser()
            //'This instruction initiate user and load roles into an User class type object
            HttpContext.Current.Session(SESSION_USER) = StructureService.GetInitializedUser(My.User.Name, UowProvider.StructureUow)
        End Sub
    
        Public Shared ReadOnly Property User() As Application.User
            Get
                //'If user doesn't exist so we create an user
    
                If HttpContext.Current.Session(SESSION_USER) Is Nothing Then ReloadUser()
    
                //'Return user
                Return CType(HttpContext.Current.Session(SESSION_USER), Application.User)
            End Get
        End Property
    
    End Class
    
    Public Class AuthentifiedRoleProvider
        Inherits RoleProvider
        //Implement base role provider....
    
        Public Overrides Function GetRolesForUser(username As String) As String()
            return SessionProvider.User.RolesList
        End Function
    
    End Class
    
        <Authorize(Roles:="UserIsAdmin")>
        Public Function List_Items() As ActionResult
            Return View()
        End Function
    
       Public Class UserProvider
    
    
        Private Const USER_CACHE_PREFIX As String = "User|"
    
        Private Shared Sub AddUserToCache(ByVal pLogin As String, ByVal pUser As Application.User)
            Dim objCache As ObjectCache = MemoryCache.Default
            objCache.Add(USER_CACHE_PREFIX & pLogin, pUser, New CacheItemPolicy With {.SlidingExpiration = TimeSpan.FromSeconds(20)})
        End Sub
    
        Private Shared Function GetUserFromCache(ByVal pLogin As String) As Application.User
            Dim objCache As ObjectCache = MemoryCache.Default
            //Return cache if exists
            If objCache.Contains(USER_CACHE_PREFIX & pLogin) Then
                Return CType(objCache.GetCacheItem(USER_CACHE_PREFIX & pLogin).Value, Application.User)
            Else
                Return Nothing
            End If
        End Function
    
        Public Shared Function ReloadUser(ByVal pLogin As String) As Application.User
            Dim objCache As ObjectCache = MemoryCache.Default
            Dim tmpLogin As String = My.User.Name
            //Clear cache
            If objCache.Contains(USER_CACHE_PREFIX & tmpLogin) Then objCache.Remove(USER_CACHE_PREFIX & pLogin)
            Dim tmpUser As Application.User = StructureService.GetInitializedUser(pLogin, UowProvider.StructureUow) 
            AddUserToCache(tmpLogin, tmpUser)
            return tmpUser
        End Function
    
        Public Shared ReadOnly Property User() As Application.User
            Get
                Dim tmpLogin As String = My.User.Name
                //Try to get user from cache
                Dim tmpUser As Application.User = GetUserFromCache(tmpLogin)
                //If user is null then init and cache
                If tmpUser Is Nothing Then
                    tmpUser = StructureService.GetInitializedUser(tmpLogin, UowProvider.StructureUow) 
                    AddUserToCache(tmpLogin, tmpUser)
    
                End If
    
                //return  user
                Return tmpUser
            End Get
        End Property
    
    End Class
    

    根据MSDN的评论,我属于第二种情况,角色管理的数据库模式不是标准的,并且由于多种原因,我无法更改它。无论如何,我确信会话存储不是存储用户数据的正确方法。因为数据不能共享BETWEN用户,所以我会考虑对象或内存。谢谢你的回答