Creating Web Custom Controls With ASP.Net 1.1 - Part VI - Handling Dependencies

The main purpose of creating controls is so they can be reused in other projects. The beauty of Web Custom Controls as opposed to Web User Controls is that they are compiled into an assembly which can easily be copied between ASP.Net projects.

When I am creating controls, I always have dependencies to support the them. At the very least, I have JavaScript that needs to be rendered for client-side behaviours of the control. I have written several controls that also rely on style-sheets and images to be used with the control. Deployment of these dependencies becomes more than a little nightmare.

Take an image for example. What happens when a control needs to render an image to the browser? It needs to render some HTML like <IMG src= 'test.gif' />. The browser then makes a request to the web server for test.gif. Thats all very well and good, but to deploy this control, you not only need to copy the controls assembly to the deployment bin folder, but also need to deploy test.gif to the correct folder to be requested by the browser. Each dependency of the control needs to be copied across each of the ASP.Net projects that use the control. This very quickly becomes a maintenance problem.

What we want to do is package all of these dependencies into the controls assembly. To achieve this, move the required files from the ASP.Net project and put them in the controls project. For each of these files, go to the property grid and set their Build Action to Embedded Resource. This will add each file as a resource to the controls assembly when it is compiled. We have now solved the deployment problem for the dependencies of the controls. When the controls assembly is copied for use in another project, all the dependencies are deployed with it as they are all bundled in the one dll file.

The next question that should be ringing around your head is how do these decencies get requested and rendered to the browser? Here is where our friend IHttpHandler comes into play. When a class implements the IHttpHandler interface, it is forced to support the ProcessRequest method. The code in this method can determine the resource being requested by the browser and take appropriate action. In the case of our dependencies, we will determine which resource is requested, extract it from the assembly and then render it to the browser.

Using IHttpHandler is perfect for covering our dependency deployment problems, but there is a just a little configuration that needs to be done in the web site to get it working. The web.config file allows us to specify a page/url reference that will cause our IHttpHandler to be called into action. This configuration causes the server to call our IHttpHandler implementing class when a specific url is requested. Just in case you are a little confused about this, the page requested doesn't actually exist, but the browser can still request it. When this happens, instead of returning a 404 error, ASP.Net hijacks the request and passes it on to the handler.

This is what is required in the web.config file:

 

<configuration>

 

   <system.web>

 

      <httpHandlers>

        <add verb="*" path="MyDev.Web.Controls.aspx" type="MyDev.Web.Controls.ResHandler,MyDev.Web.Controls" />

      </httpHandlers>

 

   </system.web>

 

</configuration>

 

We have now been able to hook up a web request to call the IHttpHandler interface in a specific class and assembly. Now when the request comes through, we need to identify which resource in the assembly is being requested.When I was originally researching this, I came across an article by Eric Woodruff that had a great idea for not only identifying the resource requested, but also supporting a caching flag. It will be through querystrings that the handler will be told what resource is being requested.

In the previous article, I discussed the best ways of rendering scripts for a control. Most control developers render the script directly to the page either when the page starts rendering, or when the page finishes rendering or when the control renders. As discussed, these scripts can be pulled out of the assembly for easier development, but rendering the script directly in the page doesn't allow for any caching of the data. With this method, a control could render a script tag that looks like <SCRIPT type='text/javascript' src='MyDev.Web.Controls.aspx?Res=MyControlScript.js' />. This causes the browser to make a separate request for the script which can now be cached by the browser. The result is that the pages will load much faster.

I created a class that implements IHttpHandler and added as many helpful features as I could think of. It will handle text and binary resources and make its best determination as to the content-type of the resource. It also supports some useful methods for registering resources with a page. As this class deals with reflection, assemblies and resources, I have cached objects and data that are often referenced and minimised the number of times the same method is called when processing the resources. Let me know if you find more improvements that can be made.

Here are the goods:

 

#Region " Imports "

 

Imports System

Imports System.Web

 

#End Region

 

''' -----------------------------------------------------------------------------

''' Project    : MyDev.Web.Controls

''' Class    : Web.Controls.ResHandler

'''

''' -----------------------------------------------------------------------------

''' <summary>

''' ResHandler object.

''' </summary>

''' <remarks>

''' Handles HTTP requests for resources in this assembly.

''' </remarks>

''' <history>

'''    [rprimrose]    25/Jan/2005    Created

''' </history>

''' -----------------------------------------------------------------------------

Public Class ResHandler

 

#Region " Declarations "

 

    Implements IHttpHandler

 

    ''' -----------------------------------------------------------------------------

    ''' Project    : MyDev.Web.Controls

    ''' Struct    : Web.Controls.ResHandler.TResType

    '''

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Stores details about a resource type.

    ''' </summary>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Structure TResType

 

        ''' -----------------------------------------------------------------------------

        ''' <summary>

        ''' The perceived type is the broad type of the resource, such as text or image.

        ''' </summary>

        ''' <remarks>

        ''' None.

        ''' </remarks>

        ''' <history>

        '''    [rprimrose]    25/Jan/2005    Created

        ''' </history>

        ''' -----------------------------------------------------------------------------

        Public PerceivedType As String

 

        ''' -----------------------------------------------------------------------------

        ''' <summary>

        ''' The content type that is specified to the client.

        ''' </summary>

        ''' <remarks>

        ''' None.

        ''' </remarks>

        ''' <history>

        '''    [rprimrose]    25/Jan/2005    Created

        ''' </history>

        ''' -----------------------------------------------------------------------------

        Public ContentType As String

 

    End Structure

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Assembly object used to cache the object reference.

    ''' </summary>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private m_objAssembly As Reflection.Assembly

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' The name of the current assemblies namespace.

    ''' </summary>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private m_sAssemblyName As String

 

#End Region

 

#Region " Constructors and Destructor "

 

#End Region

 

#Region " Events "

 

#End Region

 

#Region " Sub Procedures "

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Loads the file type information from the registry.

    ''' </summary>

    ''' <param name="sFileExt">The file extension to check.</param>

    ''' <param name="objType">The type information for the file type.</param>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private Sub LoadTypeFromRegistry( _

        ByVal sFileExt As String, _

        ByRef objType As TResType)

 

        Dim objKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." & sFileExt, False)

 

        ' Check if the Content Type exists

        If Not objKey.GetValue("Content Type") Is Nothing Then

 

            objType.ContentType = CType(objKey.GetValue("Content Type"), String)

 

        End If  ' End checking if the Content Type exists

 

        ' Check if the PerceivedType exists

        If Not objKey.GetValue("PerceivedType") Is Nothing Then

 

            ' Store the PerceivedType value

            objType.PerceivedType = CType(objKey.GetValue("PerceivedType"), String)

 

        End If  ' Check if the PerceivedType exists

 

        ' Check if the perceived type doesn't exist, but can be determined from the content type

        If objType.PerceivedType = vbNullString _

            AndAlso objType.ContentType <> vbNullString _

            AndAlso objType.ContentType.IndexOf("/") > -1 Then

 

            objType.PerceivedType = objType.ContentType.Substring(0, objType.ContentType.IndexOf("/"))

 

        End If  ' End checking if the perceived type doesn't exist, but can be determined from the content type

 

    End Sub

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Loads the file type information by the file type.

    ''' </summary>

    ''' <param name="sFileExt">The file extension to check.</param>

    ''' <param name="objType">The type information for the file type.</param>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private Sub LoadTypeFromName( _

        ByVal sFileExt As String, _

        ByRef objType As TResType)

 

        Select Case sFileExt

 

            Case "mid", "midi", "mp3", "wav", "wma"

 

                ' Toggle sfileext as appropriate for storage

                If sFileExt = "mp3" Then sFileExt = "mpeg"

                If sFileExt = "wma" Then sFileExt = "x-Microsoft-wma"

 

                objType.PerceivedType = "audio"

 

            Case "csv", "xls", "doc", "dot", "hta", "ppt", "zip", "tgz"

 

                ' Toggle sfileext as appropriate for storage

                If sFileExt = "csv" OrElse sFileExt = "xls" Then sFileExt = "vnd.Microsoft-excel"

                If sFileExt = "doc" OrElse sFileExt = "dot" Then sFileExt = "msword"

                If sFileExt = "ppt" Then sFileExt = "vnd.Microsoft-powerpoint"

                If sFileExt = "zip" Then sFileExt = "x-zip-compressed"

                If sFileExt = "tgz" Then sFileExt = "x-compressed"

 

                objType.PerceivedType = "application"

 

            Case "bmp", "gif", "jpg", "jpeg", "png", "tiff", "tif", "ico"

 

                ' Toggle sfileext as appropriate for storage

                If sFileExt = "ico" Then sFileExt = "x-icon"

                If sFileExt = "tif" Then sFileExt = "tiff"

 

                objType.PerceivedType = "image"

 

            Case "mht", "mhtml"

 

                ' Toggle sfileext as appropriate for storage

                sFileExt = "rfc822"

 

                objType.PerceivedType = "message"

 

            Case "txt", "tab", "vb", "vbs", "js", "xml", "xsl", "htc", "htm", "html"

 

                ' Toggle sfileext as appropriate for storage

                If sFileExt = "vb" OrElse sFileExt = "vbs" Then sFileExt = "vbscript"

                If sFileExt = "js" Then sFileExt = "javascript"

                If sFileExt = "txt" OrElse sFileExt = "tab" Then sFileExt = "plain"

                If sFileExt = "xsl" Then sFileExt = "xml"

                If sFileExt = "htc" Then sFileExt = "x-component"

                If sFileExt = "htm" Then sFileExt = "html"

 

                objType.PerceivedType = "text"

 

            Case "avi", "mov", "mpe", "mpeg"

 

                ' Toggle sfileext as appropriate for storage

                If sFileExt = "mov" Then sFileExt = "quicktime"

                If sFileExt = "mpe" Then sFileExt = "mpeg"

 

                objType.PerceivedType = "video"

 

            Case Else

 

                ' Default to binary data

                objType.PerceivedType = "application"

                sFileExt = "octet-stream"

 

        End Select

 

        ' Create the content type from the perceived type and the file extension

        objType.ContentType = objType.PerceivedType & "/" & sFileExt

 

    End Sub

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Registers the resource with the page.

    ''' </summary>

    ''' <param name="sResource">The name of the resource to register.</param>

    ''' <param name="objPage">The page to register the resource with.</param>

    ''' <param name="bRegisterAsStartupScript">True if the resource is to be registered as a startup script, otherwise False.</param>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Sub RegisterWithPage( _

        ByVal sResource As String, _

        ByRef objPage As UI.Page, _

        Optional ByVal bRegisterAsStartupScript As Boolean = False)

 

        ' Check if the resource is valid

        If IsValid(sResource) = True Then

 

            ' Check if we should register the resource

            If (((bRegisterAsStartupScript = False) _

                AndAlso (objPage.IsClientScriptBlockRegistered(sResource) = False)) _

                    OrElse ((bRegisterAsStartupScript = True) _

                        AndAlso (objPage.IsStartupScriptRegistered(sResource) = False))) Then

 

                ' Check if we can get a page reference

                Dim sReference As String = PageReference(sResource)

 

                ' Check if there is a reference to use

                If sReference <> vbNullString Then

 

                    ' Check if the reference is a startup script

                    If bRegisterAsStartupScript = True Then

 

                        ' Register the resource

                        objPage.RegisterStartupScript(sResource, sReference)

 

                    Else    ' This is not a startup script

 

                        ' Register the resource

                        objPage.RegisterClientScriptBlock(sResource, sReference)

 

                    End If  ' End checking if the reference is a startup script

 

                End If  ' End checking if there is a reference to use

 

            End If  ' End checking if we should register the resource

 

        End If  ' End checking if the resource is valid

 

    End Sub

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Enables processing of HTTP Web requests by a custom HttpHandler that implements the IHttpHandler interface.

    ''' </summary>

    ''' <param name="context">An HttpContext object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Sub ProcessRequest( _

        ByVal context As HttpContext) _

            Implements IHttpHandler.ProcessRequest

 

        ' Clear any existing response data

        context.Response.Clear()

 

        Try

 

            Dim sResource As String = context.Request.QueryString("Res")

            Dim bSuccess As Boolean

 

            ' Check if the resource request is valid

            If IsValid(sResource) = True Then

 

                Dim bNoCache As Boolean = False

                Dim tType As TResType = ResourceType(sResource)

 

                ' Check if NoCache has been specified

                If context.Request.QueryString("NoCache") <> vbNullString Then

 

                    Try

 

                        ' Get the cache value

                        bNoCache = System.Boolean.Parse(context.Request.QueryString("NoCache"))

 

                    Catch

 

                        ' Do nothing

 

                    End Try

 

                End If  ' End checking if NoCache has been specified

 

                With context.Response

 

                    ' Set up the response

                    .ContentType = tType.ContentType

                    .Cache.VaryByParams("Res") = True

                    .Cache.VaryByParams("NoCache") = True

                    .Cache.SetValidUntilExpires(False)

 

                    ' Check if caching is enabled

                    If bNoCache = False Then

 

                        .Cache.SetExpires(Now.AddDays(7))

                        .Cache.SetCacheability(HttpCacheability.Public)

 

                    Else    ' Caching is disabled

 

                        .Cache.SetExpires(Now.AddDays(-7))

                        .Cache.SetCacheability(HttpCacheability.NoCache)

 

                    End If  ' End checking if caching is enabled

 

                    ' Check if the type of resource is text

                    If tType.PerceivedType = "text" Then

 

                        Dim sResourceValue As String

 

                        ' Check if the resource was successfully loaded

                        If LoadTextResource(sResource, sResourceValue) = True Then

 

                            ' Write the value to the browser

                            .Write(sResourceValue)

 

                            ' Set the success flag

                            bSuccess = True

 

                        End If  ' End checking if the resource was successfully loaded

 

                    Else    ' This resource is binary

 

                        Dim aBuffer As Byte()

 

                        ' Check if the resource was successfully loaded

                        If LoadBinaryResource(sResource, aBuffer) = True Then

 

                            ' Write the value to the browser

                            .OutputStream.Write(aBuffer, 0, aBuffer.Length)

 

                            ' Set the success flag

                            bSuccess = True

 

                        End If  ' End checking if the resource was loaded successfully

 

                    End If  ' End checking if the type of resource is text

 

                End With    ' End With context.Response

 

            End If  ' End checking if the resource request is valid

 

            ' Check if the resource failed to load

            If bSuccess = False Then

 

                With context.Response

 

                    .Cache.SetExpires(Now.AddDays(-7))

                    .Cache.SetCacheability(HttpCacheability.NoCache)

                    .Status = "The resource requested doesn't exist."

                    .StatusCode = 404

                    .StatusDescription = .Status

 

                End With    ' End With context.Response

 

            End If  ' End checking if the resource failed to load

 

        Catch ex As Exception

 

            With context.Response

 

                .Cache.SetExpires(Now.AddDays(-7))

                .Cache.SetCacheability(HttpCacheability.NoCache)

                .Status = ex.Message

                .StatusCode = 500

                .StatusDescription = .Status

 

            End With    ' End With context.Response

 

        End Try

 

    End Sub

 

#End Region

 

#Region " Functions "

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Determines whether the resource name specified exists in the assembly.

    ''' </summary>

    ''' <param name="sResource">The name of the resource to find.</param>

    ''' <returns>True if the resource exists in the assembly, otherwise False.</returns>

    ''' <remarks>

    ''' If the resource name is found, the sResource value is updated to be the full name of the resource, including the assemlby name.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function IsValid( _

        ByRef sResource As String) As Boolean

 

        ' Exit if no value is specified

        If sResource = vbNullString Then Return False

 

        Dim aResources() As String = ThisAssembly.GetManifestResourceNames

        Dim sCheckName As String = sResource.ToLower

        Dim nCount As Int32

 

        ' Add the assembly namespace to the resource name if it isn't already

        If sCheckName.StartsWith(AssemblyName.ToLower) = False Then sCheckName = AssemblyName.ToLower & "." & sCheckName

 

        ' Loop through the resource names

        For nCount = 0 To aResources.Length - 1

 

            ' Check if the resource name matches

            If sCheckName = aResources(nCount).ToLower Then

 

                ' Update the resource parameter

                sResource = aResources(nCount)

 

                ' The resource was found

                Return True

 

            End If  ' End checking if the resource name matches

 

        Next    ' Loop through the resource names

 

        ' The resource wasn't found

        Return False

 

    End Function

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Returns a URL that is used to reference a resource in the assembly.

    ''' </summary>

    ''' <param name="sResource">The name of the resource.</param>

    ''' <returns>A URL that is used to reference a resource in the assembly.</returns>

    ''' <remarks>

    ''' NoCache is False by default in this handler.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function URL( _

        ByVal sResource As String, _

        Optional ByVal bNoCache As Boolean = False) As String

 

        Dim sURL As String = AssemblyName & ".aspx?Res=" & HttpUtility.UrlEncode(sResource)

 

        ' Check if NoCache is specified

        If bNoCache = True Then

 

            sURL &= "&NoCache=" & bNoCache

 

        End If  ' End checking if NoCache is specified

 

        ' Return the URL built

        Return sURL

 

    End Function

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Returns a string that can be put into a page to reference a specified resource.

    ''' </summary>

    ''' <param name="sResource">The name of the resource to reference.</param>

    ''' <returns>A string that can be put into a page to reference a specified resource.</returns>

    ''' <remarks>

    ''' This function will only return a value for specific resources types.

    ''' The return value of this function will either be a SCRIPT or IMG tag, or the resource contents itself.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function PageReference( _

        ByVal sResource As String) As String

 

        Dim tType As TResType = ResourceType(sResource)

 

        If tType.PerceivedType = "image" Then

 

            Return "<IMG src='" & URL(sResource) & "'></IMG>"

 

        ElseIf tType.ContentType = "text/css" Then

 

            Return "<LINK rel='Stylesheet' href='" & URL(sResource) & "'></LINK>"

 

        ElseIf tType.ContentType = "text/javascript" Then

 

            Return "<SCRIPT language='javascript' type='text/javascript' src='" & URL(sResource) & "'></SCRIPT>"

 

        ElseIf tType.ContentType = "text/vbscript" Then

 

            Return "<SCRIPT language='vbscript' type='text/vbscript' src='" & URL(sResource) & "'></SCRIPT>"

 

        ElseIf tType.PerceivedType = "text" Then

 

            Dim sValue As String

 

            ' Check if the resource was loaded successfully

            If LoadTextResource(sResource, sValue) = True Then

 

                ' Return the resource value

                Return sValue

 

            Else    ' The resource wasn't loaded successfully

 

                Return vbNullString

 

            End If  ' End checking if the resource was loaded successfully

 

        Else    ' This type of resource is not handled

 

            Return vbNullString

 

        End If

 

    End Function

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Returns the type of resource specified.

    ''' </summary>

    ''' <param name="sResource">The name of the resource to check.</param>

    ''' <returns>The type details of the resource.</returns>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function ResourceType( _

        ByVal sResource As String) As TResType

 

        ' Check if there is a .

        If sResource <> vbNullString _

            AndAlso sResource.LastIndexOf(".") > -1 Then

 

            ' Get the file extension

            Dim sFileExt As String = sResource.Substring(sResource.LastIndexOf(".") + 1).ToLower

            Dim objType As TResType

 

            ' Determine the file type from the registry

            Call LoadTypeFromRegistry(sFileExt, objType)

 

            ' Check if there is any type information missing

            If objType.PerceivedType = vbNullString _

                OrElse objType.ContentType = vbNullString Then

 

                Dim objTempType As TResType

 

                ' Get the type from the name

                Call LoadTypeFromName(sFileExt, objTempType)

 

                ' Store the values as appropriate

                If objType.ContentType = vbNullString AndAlso objTempType.ContentType <> vbNullString Then objType.ContentType = objTempType.ContentType

                If objType.PerceivedType = vbNullString AndAlso objTempType.PerceivedType <> vbNullString Then objType.PerceivedType = objTempType.PerceivedType

 

            End If  ' End checking if there is any type information missing

 

            ' Return the type information determined

            Return objType

 

        Else    ' An invalid value has been specified

 

            Return Nothing

 

        End If  ' End checking if there is a .

 

    End Function

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Loads a text resource from the assembly.

    ''' </summary>

    ''' <param name="sResouce">The name of the resource to load.</param>

    ''' <param name="sValue">The string the resource will be stored in.</param>

    ''' <returns>True if the resource was successfully loaded, otherwise False.</returns>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function LoadTextResource( _

        ByVal sResource As String, _

        ByRef sValue As String) As Boolean

 

        Dim bReturn As Boolean

 

        ' Check if the resource name is valid

        If IsValid(sResource) = True Then

 

            Dim tType As TResType = ResourceType(sResource)

 

            ' Check if the resource is a text resource

            If tType.PerceivedType = "text" Then

 

                Dim objStream As IO.Stream = ThisAssembly.GetManifestResourceStream(sResource)

                Dim objReader As New IO.StreamReader(objStream)

 

                Try

 

                    ' Read the resource stream

                    sValue = objReader.ReadToEnd

 

                    ' We have loaded the resource successfully, set the return flag

                    bReturn = True

 

                Catch

 

                    ' Do nothing

 

                Finally

 

                    ' Check if the reader exists

                    If Not objReader Is Nothing Then

 

                        ' Close the reader

                        objReader.Close()

 

                    End If  ' End checking if the reader exists

 

                    ' Check if the stream exists

                    If Not objStream Is Nothing Then

 

                        ' Close the stream

                        objStream.Close()

 

                    End If  ' End checking if the stream exists

 

                End Try

 

            End If  ' End checking if the resource is a text resource

 

        End If  ' End checking if the resource name is valid

 

        ' Return the success flag

        Return bReturn

 

    End Function

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Loads a binary resource from the assembly.

    ''' </summary>

    ''' <param name="sResource">The name of the resource to load.</param>

    ''' <param name="aBuffer">The buffer to store the resource contents in.</param>

    ''' <returns>True if the resource was successfully loaded, otherwise False.</returns>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public Function LoadBinaryResource( _

        ByVal sResource As String, _

        ByRef aBuffer As Byte()) As Boolean

 

        Dim bReturn As Boolean

 

        ' Check if the resource name is valid

        If IsValid(sResource) = True Then

 

            Dim tType As TResType = ResourceType(sResource)

 

            ' Check if the resource is a text resource

            If tType.PerceivedType <> "text" Then

 

                Dim objStream As IO.Stream = ThisAssembly.GetManifestResourceStream(sResource)

                Dim objReader As New IO.BinaryReader(objStream)

 

                Try

 

                    ' Resize the buffer to fit the resource

                    ReDim aBuffer(CType(objStream.Length, Int32))

 

                    ' Load the resource into the buffer

                    objReader.Read(aBuffer, 0, CType(objStream.Length, Int32))

 

                    ' We have loaded the resource successfully, set the return flag

                    bReturn = True

 

                Catch

 

                    ' Do nothing

 

                Finally

 

                    ' Check if the reader exists

                    If Not objReader Is Nothing Then

 

                        ' Close the reader

                        objReader.Close()

 

                    End If  ' End checking if the reader exists

 

                    ' Check if the stream exists

                    If Not objStream Is Nothing Then

 

                        ' Close the stream

                        objStream.Close()

 

                    End If  ' End checking if the stream exists

 

                End Try

 

            End If  ' End checking if the resource is a text resource

 

        End If  ' End checking if the resource name is valid

 

        ' Return the success flag

        Return bReturn

 

    End Function

 

#End Region

 

#Region " Properties "

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Returns a reference to the current cached assembly.

    ''' </summary>

    ''' <value>A reference to the current cached assembly.</value>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private ReadOnly Property ThisAssembly() As System.Reflection.Assembly

 

        Get

 

            ' Check if there is an assembly reference

            If m_objAssembly Is Nothing Then

 

                ' Get a reference to the assembly

                m_objAssembly = System.Reflection.Assembly.GetExecutingAssembly

 

            End If  ' End checking if there is an assembly reference

 

            ' Return the object reference

            Return m_objAssembly

 

        End Get

 

    End Property

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Gets the namespace value of the current assembly.

    ''' </summary>

    ''' <value>The namespace value of the current assembly.</value>

    ''' <remarks>

    ''' None.

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    27/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Private ReadOnly Property AssemblyName() As String

 

        Get

 

            ' Check if the value is stored

            If m_sAssemblyName = vbNullString Then

 

                m_sAssemblyName = Me.GetType.Namespace

 

            End If  ' End checking if the name is stored

 

            ' Return the stored value

            Return m_sAssemblyName

 

        End Get

 

    End Property

 

    ''' -----------------------------------------------------------------------------

    ''' <summary>

    ''' Gets a value indicating whether another request can use the IHttpHandler instance.

    ''' </summary>

    ''' <value>True if the IHttpHandler instance is reusable; otherwise, False.</value>

    ''' <remarks>

    ''' </remarks>

    ''' <history>

    '''    [rprimrose]    25/Jan/2005    Created

    ''' </history>

    ''' -----------------------------------------------------------------------------

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable

 

        Get

 

            Return True

 

        End Get

 

    End Property

 

#End Region

 

#Region " Classes "

 

#End Region

 

End Class