Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Apakah ada alternatif yang lebih efisien untuk Profil anonim ASP.NET 2.0?

Saya menerapkan solusi yang saya buat di posting asli saya, namun ternyata sedikit berbeda dari yang saya jelaskan sebelumnya. Perbaikan sebenarnya dapat dipecah menjadi 2 bagian - satu untuk memperbaiki masalah dengan database yang diperbarui saat cookie dinonaktifkan, dan yang kedua untuk mendeteksi saat cookie dinonaktifkan tanpa melakukan pengalihan.

Saya telah memposting solusi untuk profil anonim yang membuat catatan saat cookie dinonaktifkan .

Jadi sekarang saya akan fokus pada bagian kedua - memasukkan informasi ke dalam profil dari halaman pertama yang diminta. Ini hanya perlu dilakukan jika Anda melakukan pelacakan analitik atau yang serupa - bagian pertama akan melindungi database dari pengisian data yang sama sekali tidak berguna ketika 1) cookie dinonaktifkan dan 2) properti profil anonim digunakan dan berfungsi dari permintaan kedua (atau postback pertama) dan seterusnya.

Ketika saya meneliti masalah pemeriksaan untuk melihat apakah cookie diaktifkan, sebagian besar solusi menggunakan pengalihan baik ke halaman yang sama atau halaman yang berbeda dan kembali lagi. Menariknya, MSDN adalah orang yang menemukan solusi 2-pengalihan.

Meskipun dalam keadaan tertentu pengalihan dapat diterima, saya tidak ingin dampak kinerja ekstra memengaruhi sebagian besar pengguna kami. Sebagai gantinya, saya memilih pendekatan lain - gunakan AJAX untuk menjalankan kode di server setelah permintaan pertama selesai. Meskipun ini memiliki keuntungan karena tidak menyebabkan pengalihan, ini memiliki kelemahan karena tidak berfungsi saat JavaScript dinonaktifkan. Namun, saya memilih pendekatan ini karena persentase data yang hilang pada permintaan awal tidak signifikan dan aplikasi itu sendiri tidak bergantung pada data ini.

Jadi, berjalan melalui dari awal proses sampai akhir...

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not Me.IsPostBack Then

        If Session.IsNewSession Then
            Me.InjectProfileJavaScript()
        ElseIf AnonymousProfile.IsAnonymousCookieStored Then
            'If cookies are supported, and this isn't the first request, update the
            'profile using the current page data.
            UpdateProfile(Request.RawUrl, Request.UrlReferrer.OriginalString, CurrentProductID.ToString)
        End If

    End If

End Sub

Ini adalah metode Page_Load yang ditempatkan di kelas PageBase kustom saya, yang diwarisi dari semua halaman dalam proyek. Hal pertama yang kami periksa adalah apakah ini sesi baru dengan memeriksa properti Session.IsNewSession. Properti ini selalu benar jika cookie dinonaktifkan atau jika ini adalah permintaan pertama. Dalam kedua kasus, kami tidak ingin menulis ke database.

Bagian "else if" berjalan jika klien menerima cookie sesi dan ini bukan permintaan pertama ke server. Hal yang perlu diperhatikan tentang cuplikan kode ini adalah kedua bagian tidak dapat dijalankan dalam permintaan yang sama, artinya profil hanya dapat diperbarui 1 (atau 0) kali per permintaan.

Kelas AnonymousProfile termasuk dalam postingan lain .

Private Sub InjectProfileJavaScript()

    Dim sb As New StringBuilder

    sb.AppendLine("$(document).ready(function() {")
    sb.AppendLine("  if (areCookiesSupported() == true) {")
    sb.AppendLine("    $.ajax({")
    sb.AppendLine("      type: 'POST',")
    sb.AppendLine("      url: 'HttpHandlers/UpdateProfile.ashx',")
    sb.AppendLine("      contentType: 'application/json; charset=utf-8',")
    sb.AppendFormat("      data: ""{3}'RawUrl':'{0}', 'ReferralUrl':'{1}', 'ProductID':{2}{4}"",", Request.RawUrl, Request.UrlReferrer, CurrentProductID.ToString, "{", "}")
    sb.AppendLine()
    sb.AppendLine("      dataType: 'json'")
    sb.AppendLine("    });")
    sb.AppendLine("  }")
    sb.AppendLine("});")

    Page.ClientScript.RegisterClientScriptBlock(GetType(Page), "UpdateProfile", sb.ToString, True)

End Sub

Public Shared Sub UpdateProfile(ByVal RawUrl As String, ByVal ReferralUrl As String, ByVal ProductID As Integer)
    Dim context As HttpContext = HttpContext.Current
    Dim profile As ProfileCommon = CType(context.Profile, ProfileCommon)

    Dim CurrentUrl As New System.Uri("http://www.test.com" & RawUrl)
    Dim query As NameValueCollection = HttpUtility.ParseQueryString(CurrentUrl.Query)
    Dim source As String = query.Item("source")
    Dim search As String = query.Item("search")
    Dim OVKEY As String = query.Item("OVKEY")

    'Update the profile
    profile.TestValue1 = source
    profile.TestValue2 = search

End Sub

Selanjutnya, kami memiliki metode kami untuk menyuntikkan panggilan AJAX ke halaman. Perlu diingat, ini masih kelas dasar sehingga terlepas dari halaman yang dibuka pengguna di kode ini akan berjalan pada permintaan halaman pertama.

Di dalam JavaScript, pertama-tama kami menguji untuk melihat apakah cookie diaktifkan dan, jika demikian, panggil handler khusus di server menggunakan AJAX dan JQuery. Kami meneruskan parameter dari server ke kode ini (walaupun 2 di antaranya bisa saja diberikan oleh klien, byte tambahan tidak terlalu signifikan).

Metode kedua memperbarui profil dan akan berisi logika khusus saya untuk melakukannya. Saya menyertakan cuplikan tentang cara mengurai nilai string kueri dari URL parsial. Tapi satu-satunya hal yang benar-benar perlu diketahui di sini adalah bahwa ini adalah metode bersama yang memperbarui profil.

Penting: Agar panggilan AJAX berfungsi, handler berikut harus ditambahkan ke bagian system.web dari file web.config:

<httpModules>
    <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>

Saya memutuskan akan lebih baik untuk menguji cookie pada klien dan tidak melakukan panggilan AJAX tambahan jika cookie dinonaktifkan. Untuk menguji cookie, gunakan kode ini:

function areCookiesSupported() {
    var c='c';var ret = false;
    document.cookie = 'c=2;';
    if (document.cookie.indexOf(c,0) > -1) {
        ret = true;
    } else {
        ret = false;
    }
    deleteCookie(c);
    return ret
}
function deleteCookie(name) {
    var d = new Date();
    document.cookie = name + '=1;expires=' + d.toGMTString() + ';' + ';';
}

Ini adalah 2 fungsi JavaScript (dalam file .js khusus) yang hanya menulis cookie dan membacanya kembali untuk menentukan apakah cookie dapat dibaca. Ini kemudian membersihkan cookie dengan menetapkan tanggal kedaluwarsa di masa lalu.

<%@ WebHandler Language="VB" Class="Handlers.UpdateProfile" %>

Imports System
Imports System.Web
Imports System.Web.SessionState
Imports Newtonsoft.Json
Imports System.Collections.Generic
Imports System.IO

Namespace Handlers

    Public Class UpdateProfile : Implements IHttpHandler : Implements IRequiresSessionState

        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

            If AnonymousProfile.IsAnonymousCookieStored Then

                If context.Session.IsNewSession Then
                    'Writing to session state will reset the IsNewSession flag on the
                    'next request. This will fix a problem if there is no Session_Start
                    'defined in global.asax and no other session variables are written.
                    context.Session("ActivateSession") = ""
                End If

                Dim reader As New StreamReader(context.Request.InputStream)
                Dim params As Dictionary(Of String, String) = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(reader.ReadToEnd())

                Dim RawUrl As String = params("RawUrl")
                Dim ReferralUrl As String = params("ReferralUrl")
                Dim ProductID As Integer = params("ProductID")

                PageBase.UpdateProfile(RawUrl, ReferralUrl, ProductID)
            End If
        End Sub

        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property

    End Class

End Namespace

Ini adalah kelas Custom HttpHandler kami yang menerima permintaan AJAX. Permintaan diproses hanya jika cookie .ASPXANONYMOUS dilewatkan (diperiksa sekali lagi dengan menggunakan kelas AnonymousProfile dari posting saya yang lain), yang akan mencegah robot dan skrip lain untuk mengeksekusinya.

Selanjutnya kita menjalankan beberapa kode untuk memperbarui objek sesi jika diperlukan. Untuk beberapa alasan aneh, nilai IsNewSession akan tetap benar sampai sesi benar-benar diperbarui, tetapi hanya jika pengendali untuk Session_Start tidak ada di Global.asax. Jadi untuk membuat kode ini berfungsi baik dengan dan tanpa file Global.asax dan tanpa kode lain yang memperbarui objek sesi, kami menjalankan pembaruan di sini.

Kode berikutnya yang saya ambil dari postingan ini dan berisi ketergantungan ke serializer JSON.NET. Saya bingung menggunakan pendekatan ini karena ketergantungan ekstra, tetapi akhirnya memutuskan bahwa serializer JSON kemungkinan akan berharga di masa mendatang karena saya terus menambahkan AJAX dan JQuery ke situs.

Kemudian kita cukup mendapatkan parameter dan meneruskannya ke metode UpdateProfile yang kita bagikan di kelas PageBase yang telah ditentukan sebelumnya.

<!-- Required for anonymous profiles -->
<anonymousIdentification enabled="true"/>
<profile defaultProvider="SqlProvider" inherits="AnonymousProfile">
    <providers>
        <clear/>
        <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="SqlServices" applicationName="MyApp" description="SqlProfileProvider for profile test web site"/>
    </providers>
    <properties>
        <add name="TestValue1" allowAnonymous="true"/>
        <add name="TestValue2" allowAnonymous="true"/>
    </properties>
</profile>

Terakhir, kami memiliki bagian konfigurasi kami untuk properti profil, diatur untuk digunakan secara anonim (saya sengaja menghilangkan bagian string koneksi, tetapi string koneksi dan database yang sesuai juga diperlukan). Hal utama yang perlu diperhatikan di sini adalah pencantuman atribut pewarisan pada profil. Ini sekali lagi untuk kelas AnonymousProfile yang didefinisikan dalam postingan lain .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. TSQL Fungsi untuk menghitung 30 hari KERJA Tanggal dari Tanggal yang Ditentukan (SQL Server 2005)

  2. Di SQL Server 2005, bagaimana cara mendapatkan tabel di database lain yang bergantung pada tampilan?

  3. SQL tidak akan memasukkan nilai nol dengan BULK INSERT

  4. batalkan perubahan pada prosedur tersimpan

  5. Masukkan Data melalui Fungsi Bernilai Tabel di SQL Server