Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using embedded resources to improve flexibility in .NET Web applications

0.00/5 (No votes)
28 Mar 2007 1  
This article describes using embedded resources to improve flexibility in .NET Web applications.

Introduction

Have you ever had the problem of having to repeatedly copy images, style sheets etc. for every new web application? Me, not anymore. I created some code to embed all these general items into a DLL and to get these items from the DLL easily.

Background

At our company, we are developing several web applications for internal and external usage. These applications need to meet the in-house standards. In the past, we had developed a template which we copy every time we start a new application. This template includes default images, style sheets, page templates etc.

As we all know, the standard layout of things tends to change in time. Therefore, I figured: we can put all these standard things inside a library, and then only update the library DLL with an updated one when the layout has to change.

To achieve more flexibility, I defined the following problems:

  1. How can I get all layout items in a library, without having to copy all the items every time I use them?
  2. How can I get all items from the library?
  3. How can I get all items to the internet browser?

Using the code

The solution

  1. Embedded resources
  2. All VS.NET items like images, HTML pages, style sheets etc., can be marked as "embedded resource" by selecting the property page for that item and setting "Building action" to "embedded resource".

    After marking an item as an embedded resource, it will be embedded into the generated DLL, so now the DLL will contain all the layout items we need.

  3. Get embedded resources
  4. To use the embedded resources, we need some code, so I wrote two methods to get an embedded resource as a stream or as a string. The function needs the name of the embedded item and a type that is used to get the assembly where the embedded resource is located (the given type can be any type within the DLL containing the embedded resources).

    Public Class Resources
    
        Public Shared Sub GetEmbeddedResourceToStream(ByVal p_objTypeForNameSpace _
               As Type, ByVal p_strFileName As String, ByRef p_objOutputStream As Stream)
            Dim l_objAssemble As [Assembly] = _
                [Assembly].GetAssembly(p_objTypeForNameSpace)
            Dim l_objStreamReader As BinaryReader
            Dim l_strAllResources As String() = l_objAssemble.GetManifestResourceNames()
    
            l_objStreamReader = New _
              BinaryReader(l_objAssemble.GetManifestResourceStream(_
              p_objTypeForNameSpace, p_strFileName))
    
            Dim p_objInputStream As Stream = _
                l_objAssemble.GetManifestResourceStream(p_objTypeForNameSpace, _
                p_strFileName)
    
            p_objInputStream.Position = 0
            Const BUFFER_SIZE As Integer = 2048
    
            Dim l_objByteBuffer(BUFFER_SIZE) As Byte
            Dim l_intLength As Integer = _
                p_objInputStream.Read(l_objByteBuffer, 0, BUFFER_SIZE)
    
            While l_intLength > 0
                p_objOutputStream.Write(l_objByteBuffer, 0, l_intLength)
                l_intLength = p_objInputStream.Read(l_objByteBuffer, 0, BUFFER_SIZE)
            End While
        End Sub
    
        Public Shared Function GetEmbeddedResource(ByVal p_objTypeForNameSpace _
                      As Type, ByVal p_strScriptFileName As String) As String
            Dim s As StringBuilder = New StringBuilder
            Dim ass As [Assembly] = [Assembly].GetAssembly(p_objTypeForNameSpace)
            Dim sr As StreamReader 
    
            sr = New StreamReader(ass.GetManifestResourceStream(p_objTypeForNameSpace, _
                                                                p_strScriptFileName))
            s.Append(sr.ReadToEnd())
    
            Return s.ToString()
        End Function
    End Class
  5. HTTPHandlers and some streaming code
  6. So now, we have the resource embedded in a DLL, we can get the content programmatically, but how can we stream the item to a web client?

    First, you have to have some piece of code that will transform the embedded resource to an HTTPResponse. After that, we will have to be able to get the response to the client. This is all done by using an HTTPhandler.

    I created a class that looks like this:

    Imports System.Text
    Imports System.Reflection
    Imports System.IO
    
    Public Class MyResources
        Implements IHttpHandler
    
        Public ReadOnly Property IsReusable() As Boolean _
               Implements System.Web.IHttpHandler.IsReusable
            Get
                Return True
            End Get
        End Property
    
        Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) _
                   Implements System.Web.IHttpHandler.ProcessRequest
            Dim l_strEmbeddedResourceName As String
            Try
                If context.Request.QueryString.Count <> 1 Then
                    context.Response.Write("<HTML><HEAD><SCRIPT>" & _ 
                        "alert('Resource specified not found')</SCRIPT></HEAD></HTML>")
                Else
                    l_strEmbeddedResourceName = context.Request.QueryString(0)
                        ' Add embedded resources
    
                        context.Response.ClearHeaders()
                        context.Response.AddHeader("Content-Type", _
                                GetContentType(l_strEmbeddedResourceName))
                        SystemFramework.Resources.GetEmbeddedResourceToStream(Me.GetType, _
                                l_strEmbeddedResourceName, context.Response.OutputStream)
                End If
            Catch ex As Exception
                Throw ex
            End Try
    
        End Sub
    End Class

    When creating a new web application, all you have to do is add the library to the references, and add the following lines to the web.config (under system.web):

    <httpHandlers> <add verb="*" path="Resource.aspx" type="MyResources, General"/>
    </httpHandlers> 

    To get the resource in your web site, just reference it like "Resource.aspx?<resourcename>", so do something like this:

    <img src="Resource.aspx?cool.gif"/>

Hope this solution is helpful to others.

Points of interest

Mmm, the entire article, of course!

History

  • 28-03-2007: First draft.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here