Профили ASP.NET 2.0 - Как предотвратить создание записей для пользователей, которые не принимают файлы cookie? - PullRequest
1 голос
/ 09 октября 2010

Я использую профили ASP.NET с allowAnonymous = "true". Я НЕ использую членство в ASP.NET. Недавно я внимательно посмотрел на базу данных aspnetdb и заметил, что, хотя мой сайт ежедневно получает 600-800 уникальных посетителей, в базе данных создается 4000-5000 "пользователей".

Ясно, что здесь происходит, когда пользователи с отключенными файлами cookie создают запись для каждого запроса.

Мой вопрос: как предотвратить создание записей базы данных пользователей и профилей, если клиент не поддерживает файлы cookie или отключил их?

1 Ответ

1 голос
/ 11 октября 2010

После долгих исследований, проб и ошибок я нашел решение этой проблемы. Однако это решение не работает для первого запроса, который делает пользователь, поскольку невозможно определить, поддерживает ли пользователь файлы 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 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, но в этом нет особой необходимости, поскольку новый класс профиля все равно будет проверяться.

В этот пример включено еще одно исправление ошибки - исходный класс профиля будет «Грязный», если вы установите для свойства то же значение, которое оно уже содержит, что приведет к обновлению базы данных, даже если ничего не изменилось. Существует проверка этого условия в перегруженном методе 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)

...