2007-12-16

ASP.NET Images

I came across something incredibly intriguing and frustrating recently regarding ASP.NET images. [At least] In .NET 2.0 the <asp:image> renders an HTML Image control with the CSS Border explicitly turned off... unless you specify it's border using the appropriate asp:image attributes--and doing that renders out to <img src="" /> tags with embedded style attributes.

There are a few different reasons you may wish to find a better solution for this...
1.) Your website's architecture frowns upon embedded style.
2.) You're an anal-retentive developer looking to minimize wasted markup.
3.) You already pay too much for your site's bandwidth. [Markup is one of the last places to look for savings here--try reducing image, flash, and other multimedia file sizes first]

Whatever your reason, let's write a custom control to help us solve this problem! [And by all means, you can adapt this to several different problems of the same type--Video and Flash embeds, basically any Html tag you can imagine].

Let's get started.

Add a Web User Control to your project.

Your Source View will look something like this:

<%@ Control Language="C#" AutoEentWireup="true" CodeFile="Image.ascx.cs" Inherhits="inc_Html_Image" %>


Let's add code to our code behind so it looks something like this:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

///
/// Creates an image tag without the border that asp.net's image tag conveniently adds in.
///

public partial class inc_Html_Image : System.Web.UI.UserControl
{
const string _imgTag = "\";
const string _imgHeightAttribute = " height=\"{0}\"";
const string _imgWidthAttribute = " width=\"{0}\"";
const string _classAttribute = " class=\"{0}\"";
string _class = string.Empty;
string _imgSrc = string.Empty;
string _alternateText = string.Empty;
int _height = 0;
int _width = 0;
public string CssClass
{
get { return _class; }
set { _class = value; }
}

public string src
{
get { return _imgSrc; }
set { _imgSrc = value; }
}

public string ImageUrl
{
get { return _imgSrc; }
set { _imgSrc = value; }
}

public string AlternateText
{
get { return _alternateText; }
set { _alternateText = value; }
}

public int Height
{
get { return _height; }
set { _height = value; }
}

public int Width
{
get { return _width; }
set { _width = value; }
}

public override void RenderControl(HtmlTextWriter writer)
{
if (_imgSrc != string.Empty )
{
string img = string.Empty;
string imgSrc = ResolveClientUrl(_imgSrc);
string cssClass = string.Empty;
string height = string.Empty;
string width = string.Empty;
if (_class != string.Empty)
{
cssClass = string.Format(_classAttribute, _class);
}
if (_height > 0)
{
height = string.Format(_imgHeightAttribute, _height);
}
if (_width > 0)
{
width = string.Format(_imgWidthAttribute, _width);
}
img = string.Format(_imgTag, imgSrc, cssClass, _alternateText.Replace("\"", ""), height, width);
writer.Write(img);
}
}
}



And to use consume this... Drag this control onto your page...

<uc1:image id="Image1" runat="server" cssclass="SomeClassName" imageurl="~/images/someimage.jpg" alternatetext="Some alt Text">


Results are fun--Give it a shot!

No comments: