我正在使用带有allowAnonymous =“true”的ASP.NET配置文件。我不使用ASP.NET成员资格。我最近仔细研究了aspnetdb数据库并注意到虽然我的网站每天有600-800个唯一访问者,但数据库中仍有4000-5000个“用户”。
显然,这里发生的事情是禁用cookie的用户最终会为每个请求创建一条记录。
我的问题:如果客户端不支持cookie或禁用cookie,我如何防止创建用户和配置文件数据库记录?
答案 0 :(得分:1)
经过大量的研究和反复试验,我发现了这个问题的解决方案。但是,此解决方案不适用于用户发出的第一个请求,因为无法确定用户是否仅支持来自一个请求的cookie。
我想出了一个聪明的解决方案,它使用AJAX向服务器发出第二个(不可见的)请求,以便在第一个请求时将设置写入配置文件,但前提是启用了cookie和JavaScript。当然,如果您没有在初始请求中存储任何配置文件设置,则无需使用它。有关详细信息,请参阅我的other post。
Imports System.Web.Configuration
Public MustInherit Class AnonymousProfile
Inherits ProfileBase
Public Shared ReadOnly Property AnonymousCookieName() As String
Get
Dim anon As AnonymousIdentificationSection = CType(ConfigurationManager.GetSection("system.web/anonymousIdentification"), AnonymousIdentificationSection)
Return anon.CookieName
End Get
End Property
Public Shared ReadOnly Property IsAnonymousCookieStored() As Boolean
Get
Dim cookies As String = HttpContext.Current.Request.Headers("Cookie")
Return Not String.IsNullOrEmpty(cookies) AndAlso cookies.IndexOf(AnonymousCookieName) > -1
End Get
End Property
Private ReadOnly Property IsWritable() As Boolean
Get
Return IsAnonymous = False OrElse IsAnonymous AndAlso IsAnonymousCookieStored
End Get
End Property
Private Function IsObjectMatch(ByVal obj1 As Object, ByVal obj2 As Object) As Boolean
If Not obj1 Is Nothing Then
Return obj1.Equals(obj2)
Else
If obj2 Is Nothing Then
Return True
Else
Return False
End If
End If
End Function
Public Overloads Sub SetPropertyValue(ByVal propertyName As String, ByVal propertyValue As Object)
If (Not IsObjectMatch(Me.GetPropertyValue(propertyName), propertyValue)) AndAlso IsWritable Then
MyBase.SetPropertyValue(propertyName, propertyValue)
End If
End Sub
Public Overrides Sub Save()
If IsWritable Then
MyBase.Save()
End If
End Sub
End Class
简单地说,如果配置文件是匿名的并且尚未从浏览器收到匿名cookie,则此类会阻止编写或保存配置文件。
要使用此类,请将其放入App_Code目录并将“inherits”属性添加到web.config文件中的profile元素,如下所示:
<profile defaultProvider="SqlProvider" inherits="AnonymousProfile">
然后,ASP.NET将在自动生成时从此继承ProfileCommon类。
请注意,AnonymousCookieName和IsAnonymousCookieStored属性已公开共享,因此可以在项目中的任何其他位置使用它们,如下所示:
If AnonymousProfile.IsAnonymousCookieStored Then
'It is safe to write to the profile here
End If
如果用户拒绝匿名cookie,这可以节省执行不需要运行的代码的一些CPU周期,但并不是必需的,因为新的配置文件类无论如何都会检查。
此示例中还包含另一个错误修复 - 如果将属性设置为已包含的相同值,则原始配置文件类将为“Dirty”,这将导致它更新数据库,即使没有任何更改。在重载的SetPropertyValue方法中检查了这个条件,它解决了这个问题。
Public Overloads Sub SetPropertyValue(ByVal propertyName As String, ByVal propertyValue As Object)
If (Not IsObjectMatch(Me.GetPropertyValue(propertyName), propertyValue)) AndAlso IsWritable Then
MyBase.SetPropertyValue(propertyName, propertyValue)
End If
End Sub