Tuesday, February 10, 2009

Overriding javascript in webresource.axd


ASP.NET simplifies a lot of work on the programmer's part. An ASP control can render both client side and server side script. Good news for the most part, however, what if the output of the control isn't exactly what you want? There are methods in the code behind to override rendering output, but I'm going to outline a simple way to override client side javascript rendered by ASP.NET in the webresource.axd file.

My latest struggle was with the validation controls. Security in webforms is crazy important, and if you're not validating your webforms then you're open to a heap of trouble. ASP.NET offers several built in validation options:
  • RequiredFieldValidator
  • RegularExpressionValidator
  • CompareValidator
  • RangeValidator
  • CustomValidator
Each validitator provides some pre-defined client and server side functions. All of the validators derive from the BaseValidator class, which, behind the scenes (technically speaking) does some stuff. The CustomValidator is the most open to your own creations, but if you want client side validation alerts then you'll have to tie those in on your own.

My problem was with the client side code. I really wanted to use the required field and regular expression validators. I wasn't going to take the time to build my own custom validators, but I was having trouble with the default rendered output. Let me add some visual aid to the fire.

Here's a very basic form:

here's the very basic markup:

<asp:textbox ID="textBox" runat="server" />
<asp:RequiredFieldValidator
ControlToValidate="textBox"
ID="requireTextBox"
runat="server"
ErrorMessage="This field is required">
</asp:RequiredFieldValidator>

By default ASP.NET renders the textbox as an <input> and the validation control as a <span>. A screenshot of the validation and the source of the rendered tag:





The first major frustration is that the validator is rendered with inline styles. I ran all over the internet trying to find an easy way to remove this, but ASP.NET is stronger than me, I couldn't win it, so I decided to work with it. I wanted my validation to look a certain way, and this default behavior wasn't it. I have a lot of forms that have a constrained width, but extending the form down wont be a problem. I tried several methods to put the validation alert below the input. You can stick a break tag between the validator and the control to validate. I didn't like my markup being littered with <br /> tags, so I looked into putting the control to validate and the validator in seperate list items, this also cluttered my markup something fierce. I didn't know how to override the controls output method to change the <span> to a <div> or some other block level element, so I used style sheets to make the validation rendered span tags display block level. The validation controls use the CssClass attribute, in the output CssClass="" renders as class="".

I don't want to spoil the surprise, but let me lay down my desired result:

This seemed easy with a style rule added to my stylesheet:
validationControl {
display:block;
background-color:Red;
padding:5px;
margin:5px;
}

I also had to add the ForeColor="white" attribute to my RequiredFieldValidator. The control now renders style="color:white;display:hidden;". It was at this point that I realized I had a problem. What happens when I have more than one control to validate?


Notice that there's a big ugly space between my two inputs? This is because my span, even though it's hidden, is rendered block level, so it will still take up that much space on the rendered page. The incomplete fix is to add another attribute to the RequiredFieldValidator, Display="Dynamic". Dynamic changes my inline styles to display:none.

This brings me to the point: webresource.axd. All the client side functions are rendered to a dynamic file called webresource.axd, there is no file on the server that you can edit, unless you're editing/overriding your controls. There is a function inside the webresource.axd file that handles the switching of your validation. Whether you use Dynamic or not. When the page does not validate, the function switches your inline style from display="hidden", or in case of Dynamic, display="none", to display="inline". Setting my validation spans to display:block is now a mute point, the inline style overrides my stylesheet's display:block. C'mon!


Let me show you how to override the javascript function created in the webresource.axd, first, let's view the webresource.axd. I'm sure there are other developer tools out there that are going to do the same thing for you, but I used the built in dev tools to Apple Safari. In the Develop menu select the Web Inspector. This allows you to inspect the document, images, and scripts; expanding the scripts tab shows me two WebResource.axd files are loaded. There's a search box at the top of the window. I typed in "inline" which returned two results. Double clicking on the resuts locates that line withine the source code. I've copied out the function that we're going to look at:

function ValidatorUpdateDisplay(val) {
if (typeof(val.display) == "string") {
if (val.display == "None") {
return;
}
if (val.display == "Dynamic") {
val.style.display = val.isvalid ? "none" : "inline";
return;
}
}
if ((navigator.userAgent.indexOf("Mac") > -1) &&
(navigator.userAgent.indexOf("MSIE") > -1)) {
val.style.display = "inline";
}
val.style.visibility = val.isvalid ? "hidden" : "visible";
}

At line 7: val.style.display = val.isvalid ? "none" : "inline"; Without explaining too much about ternary operators, this is a compressed if statement. And where it says "inline" is the source of all that is unholy. I copied the function as it was and pasted it at the bottom of my source, before the </body>, inside of script tags. Then, you change the "inline" to "block". The important part here is that my function needs to be interpreted by the browser after the webresource.axd files are. When you view source you'll see them at the top, inside the <body> and before the <form> tag. Placing the script at the bottom is a safe bet, and it's out of the way. Here is my complete source if you're not keeping score at home:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<title>A Validation Headache</title>
<style type="text/css">
div#content {width:300px; border:solid 1px black; padding:5px;}
ul {list-style-type:none; margin:0; padding:0;}
li {padding:5px;}
.submitButton {margin-top:5px;margin-left:120px;}

.validationControl {
display:block;
background-color:Red;
padding:5px;
margin:5px;
}
</style>
</head>

<body>
<form id="form1" runat="server">
<div id="content">
<ul>
<li>
<label for="textBox">Input 1:</label>
<asp:textbox ID="textBox" runat="server" />
<asp:RequiredFieldValidator
ControlToValidate="textBox"
ID="requireTextBox"
CssClass="validationControl"
ForeColor="White"
runat="server"
Display="Dynamic"
ErrorMessage="This field is required">
</asp:RequiredFieldValidator>
</li>
<li>
<label for="textBoxTwo">Input 2:</label>
<asp:TextBox ID="textBoxTwo" runat="server" />
<asp:RequiredFieldValidator
ControlToValidate="textBoxTwo"
ID="requireTextBoxTwo"
CssClass="validationControl"
ForeColor="White"
runat="server"
Display="Dynamic"
ErrorMessage="This field is required">
</asp:RequiredFieldValidator>
</li>
<li class="submitButton">
<asp:Button ID="submitTextBox" runat="server" Text="Submit" />
</li>
</ul>
</div>
</form>
<script type="text/javascript">
function ValidatorUpdateDisplay(val) {
if (typeof(val.display) == "string") {
if (val.display == "None") {
return;
}
if (val.display == "Dynamic") {
val.style.display = val.isvalid ? "none" : "block";
return;
}
}
if ((navigator.userAgent.indexOf("Mac") > -1) &&
(navigator.userAgent.indexOf("MSIE") > -1)) {
val.style.display = "inline";
}
val.style.visibility = val.isvalid ? "hidden" : "visible";
}
</script>
</body>
</html>

Labels: , , , ,

Wednesday, February 4, 2009

Ensuring Quality Web Development: A Primer for Business Personnel

I see brand new web sites that are coded poorly all the time. A poorly-coded web site might look fine on the surface but can cause a variety of opportunity costs, maintenance headaches and other long-term issues costing far more than the initial development costs.

They slip past the radar of many business owners and managers who sponsor the work, presumably, because non-technical people typically do not have effective means of determining quality themselves, and often don't employ experts to verify quality. I offer the non-technical audience this primer to better ensure the quality of their web development projects.

I'll jump to the short-cut. Many tech-savvy managers specify that the web development coding meet at least the XHTML 1.0 Transitional and CSS 2.1 standards for projects you commission in 2009. The same goes for projects done in the last few years. Developers should know exactly what to do with these instructions. If they don't, then be sure to find developers who do. Project specs can also note the minimum browser versions to support and whether a separate version for cell phones/PDA's should be included.

When it comes to ensuring that these standards are met, one can engage a contractor such as Caliber Web Group LLC to provide Technology Project Evaluation Services to ensure quality.

For those who are ready to make some basic quality evaluations on their own, I'll offer more detail about the standards mentioned and how to ensure that they are met.

Here are a couple of gems. There are (currently free) online tools provided by the W3C that read a site page and give feedback about whether the site meets various coding standards. Take note of the coding markup validator and the style sheet validator. Both of these tools can validate a web page. The tools are used by entering URI (web address) of a web page such as http://www.caliberwebgroup.com/.

W3C CSS Validation Service


There are standards for web coding established by the W3C, the World Wide Web Consortium. When commissioning a web development project, one can specify the standards to be followed. For web development commissioned in 2009, many projects follow the XHTML 1.0 Transitional and CSS 2.1 Standards.

The old standard is HTML 4.0 which is still understood by modern desktop browsers like FireFox and Internet Explorer, but are considered significantly more difficult to maintain and update, are often not accessible by browsers for the sight-impaired, and are often completely unusable by cell phones and other smaller devices. A more in-depth history of coding standards is available here.

It's common for sites to be coded by those with a graphic design background who don't necessarily know much about coding markup. The result can be code that doesn't even match the old HTML 4.0 standard, but that looks fine visually.

Web developers can use the markup and style sheet validators while they are coding to achieve standards compliance. Some developer tools such as Microsoft Visual Studio also offer feedback during development that help a developer adhere to standards.

If a web page doesn't validate to the standards mentioned in the project specification, there should be a legitimate explanation for it. Also, there are some areas of the standard that are less critical to the maintenance and usability of the page. I'll mention some of these caveats.

Some web sites include "Flash" or "Silverlight" elements which do not pass XHTML 1.0 Transitional standards but are still acceptable features of a site. Flash players are sometimes used to embed multimedia into a web page such YouTube videos or dynamic banners. In fact, some web sites are composed almost completely of Flash movies. One thing to note is that many dynamic behaviors such as drop-down menus don't have to be coded in Flash or Silverlight, but can be coded in more simple, standards-friendly CSS.

Another caveat to the validation tools is that some warnings offered by the markup validator can be ignored with a fair degree of safety, while others should be heeded. One common, fairly optional warning has to do with encoding of the ampersand symbol in query strings.

Another important area of web development where quality really matters is the area of database integration. If the coding for database usage is not specifically coded with modern security practices, bad things can happen to good people. This is not an area where business people can afford to implicitly trust developers. I recommend third-party verification with a consulting partner such as Caliber Web Group LLC.

One of the tools that can help resolve vulnerabilities with database security and other web security issues is the McAfee Secure ® service. This service can be set up to regularly scan the site, looking for vulnerabilities. Helpful hints as to how to resolve these vulnerabilities are included with the service. This tool should be blended with internal technical personnel or third-party personnel who can prioritize and resolve the issues.

The Web is a dynamic environment that continues to evolve. Web browsers are changing along with the coding standards for web site development. The Web is also a hostile environment. Business personnel should not leave quality or security in the hands of developers without verification. If one is not able to adequately verify the work oneself, one should involve an expert.

One area that would help business personnel achieve success with Web development projects and infrastructure is a better understanding of Web browsers--how they work, what they do, how they differ between vendors, how they have evolved. Look for my primer for Web Browsers and website quality in the near future.