Asp.net mvc MVC.Net-缓存用户对象以为应用程序提供数据(请求汇总)
我真的很感激一些建议,以帮助我与对象缓存。 这是我的需要:我想根据存储在SQL数据库中的用户角色过滤控制器的一些操作 我现在要做的是:当当前用户的第一个请求完成时,我生成一个对象,其中包含一些由SQL查询初始化的属性。我使用自定义提供程序将此对象存储到会话中,并使用自定义角色提供程序处理授权筛选器标记。如果会话过期,则重新生成用户。。是这样的(简化): 用户类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
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)
- 不管怎样,你认为这个实施对实现我的目标有好处吗
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
将这样的方法放入组件之间共享的服务中意味着您不必担心在请求中多次检索相同的数据——第一次访问外部源时,以及每增加一次使用缓存时
此外,根据:
创建自定义角色提供程序有两个主要原因
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用户,所以我会考虑对象或内存。谢谢你的回答