1

我正在使用带有 allowAnonymous="true" 的 ASP.NET 配置文件。我没有使用 ASP.NET 成员资格。我最近仔细查看了 aspnetdb 数据库,发现虽然我的网站每天有 600-800 个独立访问者,但在数据库中创建了 4000-5000 个“用户”。

很明显,这里发生的是禁用 cookie 的用户最终为每个请求创建记录。

我的问题:如果客户端不支持 cookie 或禁用它们,我如何防止创建用户和配置文件数据库记录?

4

1 回答 1

1

经过大量的研究和反复试验,我找到了解决这个问题的方法。但是,此解决方案不适用于用户发出的第一个请求,因为无法确定用户是否仅通过一个请求支持 cookie。

我想出了一个聪明的解决方案,它使用 AJAX 向服务器发出第二个(不可见的)请求,以便在第一个请求时将设置写入配置文件,但前提是启用了 cookie 和 JavaScript。当然,如果您没有在初始请求中存储任何配置文件设置,则没有必要使用它。有关完整的详细信息,请参阅我的另一篇文章

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 目录中,并在 web.config 文件中的 profile 元素中添加一个“inherits”属性,如下所示:

<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 周期,但这不是绝对必要的,因为新的配置文件类无论如何都会检查。

此示例中还包含另一个错误修复 - 如果您将属性设置为它已经包含的相同值,则原始配置文件类将是“脏的”,这将导致它更新数据库,即使没有任何更改。在修复此问题的重载 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

参考:ProfileBase 类 (MSDN)

于 2010-10-10T21:49:27.097 回答