Playing with Images in ASP.NET 3.5 AJAX Applications - Loading Images from an Assembly
(Page 4 of 5 )
As we have mentioned previously, the image data for the <img> mark can be provided by several means, such as the .NET assemblies, databases, or even by dynamic means. In this section, we will discuss the assembly solution, i.e. persisting image data in system or custom assemblies.
Let us first look at the running-time snapshot for the AccessDll.aspx page, as is shown in Figure 2.
Figure 2-the running-time snapshot for the assembly solution

When designing the AccessDll.aspx page, we dragged the two important ASP.NET AJAX server side controls (ScriptManager and UpdatePanel) into the page. To achieve the partially updating effect, we've leveraged the UpdatePanel control to enclose the image area, with button labeled "Show the image in Ajax Way" as the AsyncPostBackTrigger type of trigger. For example, when you select one of the image files from the above ListBox control and press the "Show the image in Ajax Way" button, the bottom image area (in this case an ASP.NET server control Image) will display the selected image in the AJAX way. Note that the selected image data are provided by a server-side assembly named MyImageDll.
Now, let us take a quick look at the main HTML mark related code, as follows:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:ListBox ID="ResourceNames" runat="server" Height="196px" Width="332px">
</asp:ListBox>
<p>
<asp:Button ID="btnShow" runat="server" ForeColor="#003399" Height="34px"
Text="Show the image in Ajax Way" Width="187px" onclick="btnShow_Click" />
</p>
<p>
</p>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Image ID="Image1" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnShow" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Since herein only very elementary ASP.NET AJAX techniques are used, I do not plan to give detailed explanations; I will save space for more interesting things.
Now, let us shift our attention to see what happens with the code-behind file AccessDll.aspx.cs. The following gives all of the code in it:
public partial class AccessDll : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Assembly dll = Assembly.LoadWithPartialName("MyImageDll");
string[] resources = dll.GetManifestResourceNames();
ResourceNames.DataSource = resources;
ResourceNames.DataBind();
}
}
protected void btnShow_Click(object sender, EventArgs e)
{
this.Image1.ImageUrl = "GetBmpFromAssembleHandler.ashx?url=" + ResourceNames.SelectedValue;
}
}
Herein, there are two points worth noting. Inside the Page_Load function, we first created an instance of our custom assembly MyImageDll, then by invoking the GetManifestResourceNames function we obtained all the resource names contained within this assembly, and at last specified the name string array to be bound to the ListBox control.
Second, at any time when the user clicks the btnShow button (with text property being "Show the image in Ajax Way" mentioned above), the ImageUrl property of the ASP.NET server control Image is changed accordingly, with the newly-selected item from ListBox control as the new parameter passed the custom HTTP handler GetBmpFromAssembleHandler.ashx.
As we have said, the browser does not mind what kind of string the ImageUrl property specified. What it really cares about is whether the proper Content-type header is supplied and therefore the corresponding image bit stream is reached. In contrast to the first sample application above, this sample introduced another kind of simplified HTTP handler-an .ashx file, which has been registered internally into the ASP.NET configure file-web.config.
Now, let's take some time to do some research on the custom HTTP handler. The following lists all the source code for the GetBmpFromAssembleHandler.ashx file.
public class GetBmpFromAssembleHandler : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
string resourceName = context.Request["url"];
if (resourceName != null)
{
System.Drawing.Image img = LoadImageFromResources(resourceName);
if (img != null)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Jpeg );
img.Dispose();
context.Response.ContentType = "Image/jpeg";
context.Response.BinaryWrite(ms.GetBuffer());
ms.Close();
context.Response.End();
}
}
}
public bool IsReusable {
get {
return false;
}
}
private System.Drawing.Image LoadImageFromResources(string imageID)
{
Assembly dll = Assembly.LoadWithPartialName("MyImageDll");
Bitmap img = new Bitmap(dll.GetManifestResourceStream(imageID));
return img;
}
}
The implementation logic here is simple. First, obtain the passed parameter URL and judge whether it is null or not. Second, with the help of the GDI+ Image class and a helper function named LoadImageFromResources(), we grab the interesting image files out of the assembly and store them in an Image object. Third, when the above preparation is completed, an instance of the MemoryStream class is created; the image data in the above Image object are shifted into it (memory) in JPEG form. Finally, after specifying the ContentType property of HttpResponse to 'Image/jpeg' (matching the one specified above), the binary image data is written to the out stream of HttpResponse. Since here we only illustrated a simple HTTP handler, we did not put into use the try-throw-catch blocks.
Finally, let us say a few words about the MyImageDll assembly. In fact, this assembly is very simple since it only contains several picture files. Moreover, the creation process is easy, too.
To create the assembly, click 'File->Add New Project...' and from the left side (project types) select 'Visual C#-->Windows' and from the right side (templates) select 'Class Library.' Name the project MyImageDll. After you press 'OK' and exit the dialog, you will get a Class1.cs file with an empty Class1 class. Just keep it that way. Finally, create a sub folder named imgs and add several image files under it. At last, you can right click the project and select 'Build' to create an assembly named MyImageDll.dll.
To refer to the assembly is easy, too. Right above the web page project named AspnetGdiplus, select 'Add References...'. In the 'Add Reference' dialog box, click the 'Browse' tab and navigate to the MyImageDll.dll assembly. Press OK. That is all.
Next, let us discuss how to deal with image data contained inside a database under the ASP.NET scenario.
Next: Accessing Images from a SQL Server Database >>
More ASP.NET Articles
More By Xianzhong Zhu