custom caching provider for Captcha

4 posts, 0 answers
  1. Lisa
    Lisa avatar
    8 posts
    Member since:
    Oct 2012

    Posted 31 Aug 2013 Link to this post

    Hello,

    I am trying to implement a custom captcha image cache as described in your article : Captcha: Caching Provider.  I have it running successfully on my local system, storing and retrieving the images to a SQL database.  When I move the code to our web farm environment, however, it fails to instance the provider with the error below.

    I think the error has something to do with namespace but I can't figure out how to specify it.  The site in the farm environment is a virtual directory under our main website, if that makes a difference.

    I know it is able to read the appsetting from web.config, because if the web.config entry is removed, it fails with a different error.  The same error below is generated of the classname or namespace are changed to something invalid.  This leads me to believe that it fails in instancing the class.

    Any help in solving this problem would be greatly appreciated.  I'm so close to getting it to work and I really, REALLY don't want to have to change our entire environment to use out-of-process .Net session state.

    Error message, provider class code, and web.config entry follow.

    Thank you,

    Lisa



    Error:

    Server Error in '/WSCUSTSERVICE' Application.
    Value cannot be null.
    Parameter name: Unable to read application setting. Please make sure that you have set Telerik.Web.CaptchaImageStorageProviderTypeName in the web.config.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
     
    Exception Details: System.ArgumentNullException: Value cannot be null.
    Parameter name: Unable to read application setting. Please make sure that you have set Telerik.Web.CaptchaImageStorageProviderTypeName in the web.config.
     
    Source Error:
     
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
     
    Stack Trace:
     
     
    [ArgumentNullException: Value cannot be null.
    Parameter name: Unable to read application setting. Please make sure that you have set Telerik.Web.CaptchaImageStorageProviderTypeName in the web.config.]
       Telerik.Web.UI.Captcha.CachingProviderFactory..ctor(CaptchaImageStorage storage) +334
       Telerik.Web.UI.CaptchaProtector.get_CachingProvider() +52
       Telerik.Web.UI.CaptchaProtector.GenerateNewCaptcha() +160
       Telerik.Web.UI.RadCaptcha.ControlPreRender() +449
       Telerik.Web.UI.RadWebControl.OnPreRender(EventArgs e) +22
       System.Web.UI.Control.PreRenderRecursiveInternal() +80
       System.Web.UI.Control.PreRenderRecursiveInternal() +171
       System.Web.UI.Control.PreRenderRecursiveInternal() +171
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842

    The code for the provider class is:

    Imports System.Data.SqlClient
    Imports System.IO
    Imports System.Linq
    Imports System.Runtime.Serialization.Formatters.Binary
    Imports System.Web
    Imports Telerik.Web.UI
    Imports Telerik.Web.UI.Captcha
    Imports WalkStyles.Common
    Imports System.Data
     
     
    Namespace CustService
     
     
        Public Class DBImageStorageProvider
            Inherits BaseCaptchaCachingProvider
            Public Sub New(ByVal context As HttpContext)
                MyBase.New(context)
            End Sub
     
            Private Function connectionString() As String
                '' = "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|CachingProviderDatabase.mdf;Integrated Security=True;User Instance=True;"
                Return ConfigMgr.ConfigSetting(ConfigMgr.CK_DSN)
            End Function
     
            Public Overrides ReadOnly Property ShouldAddCacheDependecy() As Boolean
                Get
                    Return True
                End Get
            End Property
     
            Public Overrides Sub Save(ByVal key As String, ByVal image As CaptchaImage)
                Using conn As SqlConnection = GetConnection(connectionString)
                    conn.Open()
                    Using command As SqlCommand = New SqlCommand("INSERT INTO [RadCaptchaImageCache] ([ImageKey], [ImageContent]) VALUES (@key, @value)", conn)
                        Using ms As MemoryStream = SerializeImage(image)
     
                            command.Parameters.Add("@key", SqlDbType.NVarChar, 100)
                            command.Parameters("@key").Value = key
     
                            command.Parameters.Add("@value", SqlDbType.VarBinary, Int32.MaxValue)
                            command.Parameters("@value").Value = ms.GetBuffer()
     
                            ''command.Parameters.Add(New SqlParameter("key", key))
                            ''command.Parameters.Add(New SqlParameter("value", ms))
     
                            command.ExecuteNonQuery()
                        End Using
                    End Using
                End Using
            End Sub
     
            Public Overrides Function Load(ByVal key As String) As CaptchaImage
                Dim result As CaptchaImage = Nothing
                Using conn As SqlConnection = GetConnection(connectionString)
                    conn.Open()
                    Using command As SqlCommand = New SqlCommand("SELECT [ImageContent] FROM [RadCaptchaImageCache] WHERE [ImageKey] = @key", conn)
                        command.Parameters.Add(New SqlParameter("key", key))
                        Dim bData As Byte() = DirectCast(command.ExecuteScalar(), Byte())
     
                        Using ms As MemoryStream = New MemoryStream()
                            result = DeserializeImage(bData, ms)
                        End Using
                    End Using
                End Using
     
                Return result
            End Function
     
            Public Overrides Sub Clear(ByVal key As String)
                Using conn As SqlConnection = GetConnection(connectionString)
                    conn.Open()
                    Using command As SqlCommand = New SqlCommand("DELETE FROM [RadCaptchaImageCache] WHERE [ImageKey] = @key", conn)
                        command.Parameters.Add(New SqlParameter("key", key))
                        command.ExecuteNonQuery()
                    End Using
                End Using
            End Sub
     
     
            Private Function GetConnection(ByVal connString As String) As SqlConnection
                Return New SqlConnection(connString)
            End Function
     
            Private Function SerializeImage(ByVal image As CaptchaImage) As MemoryStream
                Dim ms As MemoryStream = New MemoryStream()
                Dim bFormatter As BinaryFormatter = New BinaryFormatter()
                bFormatter.Serialize(ms, image)
                ms.Seek(0, 0)
     
                Return ms
            End Function
     
            Private Function DeserializeImage(ByVal bData As Byte(), ByVal ms As MemoryStream) As CaptchaImage
                Dim bFormatter As BinaryFormatter = New BinaryFormatter()
     
                ms.Write(bData, 0, bData.Length)
                ms.Seek(0, 0)
     
                Return DirectCast(bFormatter.Deserialize(ms), CaptchaImage)
            End Function
     
     
        End Class
     
    End Namespace


    The web.config entry for the provider is:

    <!-- ================================================================= -->
    <!-- Image storage cache handler for radCaptcha controls               -->
    <!--                                                                   -->
    <add key="Telerik.Web.CaptchaImageStorageProviderTypeName" value="CustService.DBImageStorageProvider, App_Code.lfcwuanr, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"/>

  2. Slav
    Admin
    Slav avatar
    1355 posts

    Posted 04 Sep 2013 Link to this post

    Hello Lisa,

    We have tested the described scenario, however we did not encounter the problem with the custom captcha image provider in a web farm environment. Nevertheless, a similar error occurred when the appSettings key in web.config was missing in one of the web farm servers.

    Since the setup you have posted appears to be correct and the encountered error indicates that the application setting for the image provider is missing, I would suggest checking whether one or more of the web farm servers are not synced. If the appSetting is missing in one of the web.config files this error will most probably occur.

    I have attached the sample project that was used for testing the captcha in the load balanced environment so that you can try it locally and check if there are differences in the setup, compared to your actual project.

    Regards,
    Slav
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Lisa
    Lisa avatar
    8 posts
    Member since:
    Oct 2012

    Posted 11 Sep 2013 Link to this post

    Thank you, but the project you sent is really nothing more than the code that is available in your help documentation. 

    I am no farther along in getting the problem solved.  Unfortunately, we don't have a farmed test environment, and I'm restricted to how much I can do in our production environment.  I will have to remove the use of the control and table the problem until I can production release the rest of the application.  Then I will try to add the control back in.
  5. Slav
    Admin
    Slav avatar
    1355 posts

    Posted 16 Sep 2013 Link to this post

    Hi Lisa,

    Indeed, the sample I sent has the same setup as the one shown in the help article, because I wanted to provide a project that is tested and working on a common web farm.

    Please ensure that the versions of the web.config file in all machines of your web farm are synchronized as this is the only cause for the problem that is currently known.

    If you find information that suggest the issue stems from something else, please send it for further inspection as there could be a bug with the captcha control that we missed.

    Regards,
    Slav
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
Back to Top