Fixing ASP.NET Server Control Rendering Issues with Tag Mapping
Extraneous attributes. Default styles. Stray markup. Sometimes, ASP.NET server controls just don't render the way you want them to. Even in those cases where Microsoft is just trying to be "helpful", sometimes I just want them to get out of the way and let me do my thing. Here, I'll demonstrate a quick-and-dirty way to get rid of that extra markup, using the
I was greeted this morning by this blog post from my friend Anthony Grace over at CodersBarn.com. In it, Anthony writes:
Recently, I have been experiencing some difficulty applying CSS correctly to some of the OOTB (out-of-the-box) ASP.NET controls. Earlier today, I was trying to apply a CSS image border using the ASP.NET image control, but couldn't get it to render correctly. In the end, I had to use a regular HTML img tag.
Ouch. It seems he's been bitten by the ASP.NET Image Border Style Bug um, Feature. And if you've ever tried to apply border styles via CSS to the
How ASP.NET Renders the Image Server Control
You see, when you place an Image server control on a page, like this:
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/girl.jpg" />
Figure 1
It renders onto the page as follows:
See that inline style="border-width:0px;" attribute in the img tag? We didn't put that there, Microsoft did. I suspect they do this to get rid of the ugly default border that is applied by most browsers to image hyperlinks. I don't really know. All I know is this a big P.I.T.A. when you're trying to style the
<%@ Page Language="C#" %>
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Image Bordertitle>
<style type="text/css">
.imageStyle {
padding: 6px;
background-color: #CCCCCC;
border: 2px solid #0099CC;
}
style>
head>
<body>
<form id="form1">
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/girl.jpg"
CssClass="imageStyle" />
form>
body>
html>
Figure 2
The page above results in the following source output:
Image Border
Which, when rendered onto the page, looks like this:
Figure 3
You can see back in Figure 2, we've defined our .imageStyle class and properly specified it via the CssClass property of the Image tag. The background color and padding render fine. So, where did our pretty blue border go? If you understand the cascade part of CSS, you know that the inline style="border-width:0px;" attribute added by the default rendering overrides any border styles we set from the page level, or from an external CSS stylesheet.
The Solution
There are actually several workarounds for this. You can override the style in the page's OnPreRender event. You can set the border width on all Image tags at the control level by setting the BorderWidth property (though this pretty much defeats the advantages of using CSS). And of course, you can use a regular HTML tag, which is what Anthony did.
Or, you can forget about using a "workaround" and fix the real problem. You can do that by deriving a new class from System.Web.UI.WebControls.Image and applying it automatically to all
First, create a new class (I'm calling this one ImageBorderless) that derives from Image:
using System.Web.UI.WebControls;
public class ImageBorderless : Image
{
public override Unit BorderWidth
{
get { return base.BorderWidth.IsEmpty ? Unit.Pixel(0) : base.BorderWidth; }
set { base.BorderWidth = value; }
}
}
Figure 4
Then, in your web.config file, in the
<pages>
<tagMapping>
<add tagType="System.Web.UI.WebControls.Image" mappedTagType="ImageBorderless" />
tagMapping>
pages>
Figure 5
This tag mapping simply maps all instances of the Image tag to the ImageBorderless type.
Rerun the page, and you'll see that pesky style attribute is now gone, and that the page renders correctly.
Image Border
Figure 6
Conclusion
As handy as ASP.NET server controls are (most of the time), sometimes anomalous rendering issues make it tricky to have them look or behave the way we want. When that happens, you can always derive a new control, override properties and behaviors as needed, and map that wayward tag to your derived type via tag mapping.
Have fun!
Subscribe to this blog for more cool content like this!
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Thank you for submitting this cool story - Trackback from DotNetShoutout