Delayed Script/Waiting in Javascript

I was struggling in finding out of how to make a simple delegate like in AJAX request through javascript. It takes me a few days to figure this out

Basically the problems are:

-I need to execute a piece code of javascript after getting the ticket from web service function

-The webservice function might not be responding to the first request because it waits for the state of the other external component

-The webservice will give the response when the external component is ready

-The client does not know when the external component is ready, neither the web service. But it wil be ready within 1-5 minutes which again depending external component

Possible Solution:

-Using the setTimeOut(function(){acquireTicket();}, 300000) will cause the application to wait for 5 mins before calling the web service , this approach will slowing down the user experience and waste of time because the external component can be ready earlier than 5 mins

-Using the while loop is not good because it makes the browser freezing while waiting and it will wasting the processing power because of the looping

Recommended Solution:

-Recall the function by itself using setTimeout Function using parameter to indicate whether it should go out of the loop or not

-The web service will be checked for every 2 seconds to check the response from the external component. Once the external component is ready then it will move on to execute the next line of code

Access javascript object properties with invalid character

ParseJSON returning you an object from your AJAX Call, the problem that I have is my object properties has invalid character (e.g “#”)

Assuming jsonData is my variable that contains the following information

I’d like to grab the property of “#innerxml”

Normally I can do this to get the property of an object but in this case I can’t due to invalid character

(jQuery.parseJSON(jsonData)[0]).#innerxml

So How do I access an object which has properties where one of the property name is using an invalid character (e.g “#”)

I can access with the following style

(jQuery.parseJSON(jsonData)[0])[‘#innerxml’]

Remapping svc extension in IIS 7 extension handlers

If you open your WCF/ svc file in your localhost through browser and it just display blank page then what might happen is you don’t have handler associated with svc extension

To verify it, go to your IIS and go to IIS Handler Mappings and try to find an svc extension entry, but if you couldn’t find extension SVC exists on the list, then you can remap/re-add the svc extension by running

C:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\ServiceModelReg.exe –i

*if you are still using 32 bit then you just need to replace Framework64 with Framework

Simple Collapsible Panel using JQuery

I found a simple collapsible panel developed by a guy called Darren Ingram and I’d definitely recommend it to anyone wanted to implement collapsible panel. His Jquery implementation of collapsible panel is very simple. It just need 2 files (diQuery-collapsiblePanel.js and diQuery-collapsiblePanel.css – where the css classes can even be integrated to your own css class). I prefer this implementation because it’s just a div implementation and the JQuery script will be hooked up to the div elements (where the class name is collapsibleContainer) upon the page loaded. Simple and lightweight in comparison to the collapsible panel of AJAX toolkit (http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/CollapsiblePanel/CollapsiblePanel.aspx)

the source code for the collapsible panel by Darren Ingram can be downloaded from his website (http://www.darreningram.net/pages/examples/jQuery/CollapsiblePanelPlugin.aspx)

Enter button in TextBox ASP.NET

This article is demonstrating how to wire up an enter key into a textbox. For example you have a search text box where you press enter then it will click go button and at the same page you have another textbox where you want to do another button click when you press the enter which means it’ is not necessary to post the page. This java script is used to capture the key event of enter and execute the LinkButton and ASP.NET button Click Event on the server side. Please add this javascript to your javascript common library or add this to your master page. This piece of code works in Firefox as well


function ButtonKeyPress(evt, thisElementName)
{
    if(evt.which || evt.keyCode)
    {
        if ((evt.which == 13) || (evt.keyCode == 13))
        {
            // alert('post back href: ' +document.getElementById(thisElementName).href);

            if (typeof document.getElementById(thisElementName).href != 'undefined')
            {
                location = document.getElementById(thisElementName).href;
            }
            else
            {
                document.getElementById(thisElementName).click();
            }
            return false;
        }
    }
    else
    {
        return true;
    }
}

And add this to your .NET code behind on the page load

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
         If Not Page.IsPostBack Then


            If (User.Identity.IsAuthenticated) Then
                Response.Redirect("frmTimeMain.aspx")
            End If

            txtGUID.Attributes.Add("onkeydown", "ButtonKeyPress(event, '" + lnkSubmit.ClientID + "')")
            txtPassword.Attributes.Add("onkeydown", "ButtonKeyPress(event, '" + lnkSubmit.ClientID + "')")
          End If
    End Sub

ASP.NET Calendar selected day on click method

I’ve a case where I have an ASP.NET calendar that has a page load method that automatically select a date when it’s loaded. I also have an event defined for Selected_Changed which will be triggered only when the user select any other date other than pre-selected date on the load

Private Sub ctlCalendar_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctlCalendar.SelectionChanged
        If (Not String.IsNullOrEmpty(CalendarPreviousPage)) Then
            BaseCalendar.SelectedDate = ctlCalendar.SelectedDate
            Response.Redirect(CalendarPreviousPage)
        End If
    End Sub

But how do I wire up an event or when the selecteddate being clicked?You can use DayRender event and attach it to a javascript in this case I want to go back to previous page. BaseCalendar.Selected date can be any date where you want to set up/wire up the logic

 Private Sub ctlCalendar_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Handles ctlCalendar.DayRender
        Dim d As CalendarDay
        Dim c As TableCell
        d = e.Day
        c = e.Cell

        If (BaseCalendar.SelectedDate.Value = d.Date) Then
            c.Attributes.Add("OnClick", "history.go(-1)")
        End If

    End Sub

Reflection GetProperty case sensitive issue

Reflection on .NET by default is case sensitive for the class member. To make it case insensitive you need to pass BindingFlags.IgnoreCase . I’ve passed the ignorecase flag and now it doesn’t return anything!!!


 Dim pi As PropertyInfo = Me.[GetType]().GetProperty(fieldname, BindingFlags.IgnoreCase)

Basically, if you pass one flag then the other flags will be overwritten by default which means all the default flags are disappeared. So to make it case insensitive then you need to pass other binding flags


 Dim pi As PropertyInfo = Me.[GetType]().GetProperty(fieldname, BindingFlags.IgnoreCase Or BindingFlags.Public Or BindingFlags.Instance)

Compression in Silverlight Isolated Storage

Isolated storage in silverlight is used to store information or object therefore we don’t need to go to database to get all the information over and over again but again to use isolated storage or not should be based on case by case. Based on the implementation of the code below, I’ve found that it can compress the isolated storage file from 0.8Mb becoming 0.1 MB which is great enough for me since the quota limit is 1 mb and we try not to exceed that limit.

I’ve got this compression method from Peter Bromberg blog.

This compression method is a wrapper to SharpZip Library for Silverlight, you can download it from here, you need this library before using the code below. You can download the code below from here.

I’ve also created a Isolated Storage File with the assembly version as the file name to make sure that we have clean isolated storage file assuming the uncompressed version of isolated storage is already in production and we need to clean it up. “AssemblyVersion” properties will return the property of the current version no of the running assembly. CheckIsolatedStorageFileVersion will make sure that we always have the clean isolated storage for the new assembly.

Sample of usage
1. How to read/deserialize object from isolated storage

 Dim objMessageCodes As MessageCodes = GetIsolatedStorage(Of MessageCodes)("MyFile.txt")

2. How to write/serialize object to isolated storage

      Dim _messageCodes As New MessageCodes(mListMessage)
      WriteIsolatedStorage(_messageCodes, "myfile.txt")

These are the definition of the above function to serialize/deserialize object from your silverlight, this function is created based on Generic so it’s flexible enough to accept anything

Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.Threading
Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Xml.Serialization
Imports System.Runtime.Serialization
Imports System.Reflection

Public Class MySL
 Private mAppStorage As IsolatedStorageFile

    ''' 
    ''' This is used to write the compressed object to Isolated Storage
    ''' 
    ''' 
    ''' 
    Private Sub WriteIsolatedStorage(Of T)(ByVal obj As T, ByVal filename As String)
        Try
            Dim xmlByte As Byte() = Compression.SerializeAndCompress(obj)

            Using _stream As IsolatedStorageFileStream = mAppStorage.CreateFile(filename)
                _stream.Write(xmlByte, 0, xmlByte.Length)
            End Using
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    ''' 
    ''' this is used get the compressed object from Isolated storage
    ''' 
    ''' 
    ''' 
    ''' 
    ''' 
    Private Function GetIsolatedStorage(Of T)(ByVal fileName As String) As T
        Try
            Using _stream As IsolatedStorageFileStream = mAppStorage.OpenFile(fileName, FileMode.Open)
                Using _reader As BinaryReader = New BinaryReader(_stream)
                    Dim tmpBytes As Byte()
                    ReDim tmpBytes(1024)
                    Dim fullBytes As Byte() = Nothing
                    Dim xmlStream As MemoryStream = New MemoryStream()

                    While True
                        Dim read As Integer = _reader.Read(tmpBytes, 0, tmpBytes.Length)

                        If (read <= 0) Then
                            fullBytes = xmlStream.ToArray()
                            Exit While
                        End If

                        xmlStream.Write(tmpBytes, 0, read)
                    End While

                    Dim xmlTempbyte As Byte() = xmlStream.ToArray()
                     Return Compression.DecompressAndDeserialize(Of T)(xmlTempbyte)
                End Using

            End Using

            Return Nothing

        Catch ex As Exception
            Throw ex
        End Try

    End Function

Private _compression As Compression = Nothing

    Private ReadOnly Property Compression() As Compression
        Get
            If (_compression Is Nothing) Then
                _compression = New Compression()
            End If

            Return _compression
        End Get
    End Property

    ''' 
    ''' get the assembly version
    ''' 
    ''' 
    ''' 
    ''' 
    Private ReadOnly Property AssemblyVersion() As String
        Get
            Dim name As String = Assembly.GetExecutingAssembly().FullName
            Dim asmName As AssemblyName = New AssemblyName(name)
            Return asmName.Version.ToString().Replace(".", "")
        End Get
    End Property

''' 
    ''' try to clear isolated storage
    ''' 
    ''' 
    Private Sub CheckIsolatedStorageFileVersion()
        Try
            Dim isoStorage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForSite

            If Not mAppStorage.FileExists(AssemblyVersion + ".txt") Then
                'clear all the isolated storage
                isoStorage.Remove()
                mAppStorage.Remove()

                mAppStorage = IsolatedStorageFile.GetUserStoreForApplication()

                Using _stream As IsolatedStorageFileStream = mAppStorage.CreateFile(AssemblyVersion + ".txt")
                    Using sw As StreamWriter = New StreamWriter(_stream)
                        sw.Write(AssemblyVersion)
                    End Using
                End Using
                'Throw New Exception("Clearing!!!")
            End If

        Catch ex As Exception
            Throw ex
        End Try
    End Sub

End Class

Wrapper Class to SL SharpZipLib

Imports System
Imports System.Text
Imports System.IO
Imports System.Collections
Imports System.Diagnostics
Imports System.Collections.Generic
Imports System.Runtime.Serialization
Imports ICSharpCode.SharpZipLib.Zip.Compression
Imports System.Xml.Serialization
Imports System.Text.RegularExpressions

Public Class Compression

    Public Sub New()
    End Sub

    Public Function Serialize(Of T)(ByVal inst As T) As Byte()
        Dim dcs As New DataContractSerializer(GetType(T))

        Using ms As New MemoryStream
            dcs.WriteObject(ms, inst)
            Return ms.ToArray()
        End Using

    End Function

    Public Function Deserialize(Of T)(ByVal objectData As Byte()) As T
        Dim dcs As New DataContractSerializer(GetType(T))

        Using ms As New MemoryStream(objectData)
            Return CType(dcs.ReadObject(ms), T)
        End Using

    End Function

    Public Function SerializeAndCompress(Of T)(ByVal inst As T) As Byte()
        Dim b As Byte() = Serialize(Of T)(inst)
        Return Compress(b)
    End Function

    Public Function DecompressAndDeserialize(Of T)(ByVal bytData As Byte()) As T
        Dim bytes As Byte() = Decompress(bytData)
        Return Deserialize(Of T)(bytes)
    End Function

    Public Function Compress(ByVal strInput As String) As Byte()
        Try
            Dim bytData As Byte() = System.Text.Encoding.UTF8.GetBytes(strInput)
            Dim ms As New MemoryStream()
            Dim defl As New Deflater(9, False)

            Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
                s.Write(bytData, 0, bytData.Length)
                s.Close()
            End Using

            Return DirectCast(ms.ToArray(), Byte())
        Catch
            Throw

        End Try
    End Function

    Public Function Compress(ByVal bytData As Byte()) As Byte()
        Try

            Dim ms As New MemoryStream()
            Dim defl As New Deflater(9, False)

            Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
                s.Write(bytData, 0, bytData.Length)
                s.Close()
            End Using

            Return DirectCast(ms.ToArray(), Byte())
        Catch
            Throw

        End Try
    End Function

    Public Function Compress(ByVal bytData As Byte(), ByVal ParamArray ratio As Integer()) As Byte()

        Dim compRatio As Integer = 9
        Try
            If ratio(0) > 0 Then
                compRatio = ratio(0)
            End If
        Catch

        End Try

        Try
            Dim ms As New MemoryStream()
            Dim defl As New Deflater(compRatio, False)

            Using s As Stream = New Streams.DeflaterOutputStream(ms, defl)
                s.Write(bytData, 0, bytData.Length)
                s.Close()
            End Using

            Return DirectCast(ms.ToArray(), Byte())
        Catch
            Throw
        End Try
    End Function

    Public Function Decompress(ByVal bytInput As Byte()) As Byte()
        Try

            Dim ms As New MemoryStream(bytInput, 0, bytInput.Length)
            Dim bytResult As Byte() = Nothing
            Dim strResult As String = [String].Empty
            Dim writeData As Byte() = New Byte(4095) {}

            Using s2 As Stream = New Streams.InflaterInputStream(ms)
                bytResult = ReadFullStream(s2)
                s2.Close()
            End Using

            Return bytResult
        Catch
            Throw
        End Try
    End Function

    Public Function ReadFullStream(ByVal stream As Stream) As Byte()
        Dim buffer As Byte() = New Byte(32767) {}
        Using ms As New MemoryStream()
            While True
                Dim read As Integer = stream.Read(buffer, 0, buffer.Length)
                If read <= 0 Then
                    Return ms.ToArray()
                End If
                ms.Write(buffer, 0, read)
            End While
        End Using

        Return buffer
    End Function

End Class

FormsAuthentication.GetRedirectUrl only get the first parameter of querystring

I found the issue with FormsAuthentication.GetRedirectUrl when it redirects then it redirects with the first querystring that you have while in fact you might have more than one querystring

e.g http://localhost/myweb/login.aspx?returnurl=myview.aspx?viewID=123&viewname=abc&viewall=false then the standard FormsAuthentication will redirect to http://localhost/myweb/myview.aspx?viewID=123

but where’s the remaining viewname querystring and viewall querystring??to fix this, just use the code below to pick the remaining querystring

Methods:

  'this is used to fix the issue with FormsAuthentication.GetRedirectUrl only pick the first query string
            'get the original Redirect URL
            Dim redirectUrl As StringBuilder = New StringBuilder(FormsAuthentication.GetRedirectUrl(" ", True))
            Dim coll As NameValueCollection = objRequest.QueryString

            'iterate through every key in query string
            'add the missing query string
            For Each key As String In coll.AllKeys
                If (String.Compare(key, "returnurl", True)  0) Then
                    Dim values As String() = coll.GetValues(key)

                    If (values.Length > 0) Then
                        Dim pair As String = String.Format("{0}={1}", key, values(0))

                        If (redirectUrl.ToString().IndexOf(pair) < 0) Then
                            redirectUrl.Append("&" + pair)
                        End If
                    End If
                End If
            Next

            'this is to retain the original URL as in the query string
            objResponse.Redirect(redirectUrl.ToString())

Resolve URL functions

This snippet code is credited to Scott’s Hanselman, This Resolve URL function is used where you want to implement it on your business layer.

Methods:


        #region "Image URL helpers"

        public static string ResolveUrl(string originalUrl)
        {
            if (originalUrl == null)
                return null;
            // *** Absolute path - just return
            if (originalUrl.IndexOf("://") != -1)
                return originalUrl;
            // *** Fix up image path for ~ root app dir directory
            if (originalUrl.StartsWith("~"))
            {
                string newUrl = "";
                if (System.Web.HttpContext.Current != null)
                    newUrl = System.Web.HttpContext.Current.Request.ApplicationPath + originalUrl.Substring(1).Replace("//", "/");
                else  // *** Not context: assume current directory is the base directory
                    throw new ArgumentException("Invalid URL: Relative URL not allowed.");
                // *** Just to be sure fix up any double slashes
                return newUrl;
            }
            return originalUrl;
        }

        /// Works like Control.ResolveUrl including support for ~ syntax
        /// but returns an absolute URL.
        /// 
        /// Any Url, either App relative or fully qualified
        /// if true forces the url to use https
        /// 
        public static string ResolveServerUrl(string serverUrl, bool forceHttps)
        {    // *** Is it already an absolute Url?
            if (serverUrl.IndexOf("://") > -1)
                return serverUrl;
            // *** Start by fixing up the Url an Application relative Url
            string newUrl = ResolveUrl(serverUrl);
            Uri originalUri = System.Web.HttpContext.Current.Request.Url;
            newUrl = (forceHttps ? "https" : originalUri.Scheme) + "://" + originalUri.Authority + newUrl;
            return newUrl;
        }

        /// 
        /// This method returns a fully qualified absolute server Url which includes
        /// the protocol, server, port in addition to the server relative Url.
        ///
        /// It work like Page.ResolveUrl, but adds these to the beginning.
        /// This method is useful for generating Urls for AJAX methods
        /// 
        /// Any Url, either App relative or fully qualified
        /// 
        public static string ResolveServerUrl(string serverUrl)
        {
            return ResolveServerUrl(serverUrl, false);
        }

        #endregion

Usage:

 sb.AppendFormat("

", row.WidgetItemClass); sb.AppendFormat("More Info", ProductsService.GetProductUrl(row.ProductID), ResolveServerUrl("~/GetWhiteLabelFile.aspx?whiteLabelFileID=" + row.WidgetItemLinkImageID.ToString())); sb.AppendFormat("

");