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