Showing posts with label basics. Show all posts
Showing posts with label basics. Show all posts

SOLVED: Firebug Inspect Element Keyboard Shortcut Clash

Posted on: Friday, 3 June 2011 22:05

If you want to use the Ctrl-Shift-C shortcut to Inspect Element in Firebug but you also have the Web Developer plugin installed then read on to to find out how to stop them clashing!

A simple way to add some flair to your site with a favicon

Posted on: Saturday, 24 October 2009 21:03

I am going to explain how you can get that little icon that appears next to the url in the address bar on many of your favourite sites. You will also find it next to its name if you add it to your favourites.

Here are some sample favicon's taken from the Firefox address bar:

favicon-image-examples

So now that we're all on the same page as to what a favicon is I will get down to the technical side of it. The favicon is obviously an abbreviation of "favourites icon". Favourites are bookmarks in the IE world which is where this idea started out its existence.

The modern favicon standard (it was standardised in 2003) is a lot more flexible than its original inception.

A little background

The favicon was a 16x16 icon which had to be in the Microsoft icon format, placed in the root of your website, and called favicon.ico. Because of these requirements the browser could automatically detect if your site has a favicon available.

Now that it has been standardized you can put the file in any location. The number of file types has been expanded as well as the number of sizes of icon you can support.

Because you can put the favicon anywhere now you have to notify the browser by putting a <link> tag in your web pages. Before this was settled on there were two ways to define it - rel="icon" and rel="shortcut icon".

The final standardisation solved all the problems with the early versions of favicons. The fixed file name is known as url squatting which is frowned on. The file type was a Microsoft proprietary format. The <link> rel tag didn't follow the proper space-delimited list standardisations (it used two separate keywords to mean a single keyword).

Even with all of these problems solved I must admit that I still take a traditional approach my favicons. I save them as favicon.ico in the root of my websites, in MS icon format and do  belt and braces with the link tag by including both a rel="shortcut icon" and rel="icon". Its probably overkill but for such a simple feature I feel that adhering to the original standards means that my favicons will be supported by the widest possible number of browsers.

How do you make yours?

I am going to skip over the part where you make a 16x16 graphic and try to cram your logo into it. If you don't have any artistic skills yourself then you can turn to a friendly artist on your team or reach out to the community.

For some reason icon file format support has never been included in Photoshop so while you can make your brilliant 16x16 graphic in that program you will have to turn to a 3rd party to get it in the correct format.

There are various plugins for Photoshop available and online generators which can help you with this.

And don't forget that you aren't forced to use the ico file format with modern browsers, png, gif and jpeg are all valid formats.

How to you link in into your site?

Personally, as I said above, I call my icons favicon.ico in the root folder of my website. That would be enough to get it to show up in all modern browsers. I also put the <link> tags which look like this (xhtml snippet - remove the trailing / if you are working in html)

<link rel="icon" href="/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon" />

So now you know how to add that extra flair into your next website project. Its completely up to you if you want to follow my old school approach or if you want to take full advantage of the newer features such as multiple icon sizes, animated gifs and different filenames and locations - these will still work on the majority of modern browsers. You could always throw in a backup favicon.ico in the root for the old browsers "just in case".

Further Reading

kick it on DotNetKicks.com Shout it

Dynamic meta description and keyword tags for your MasterPages

Posted on: Wednesday, 21 October 2009 18:00

Today we're going to look at a technique for dynamically inserting meta tags into your master pages. By taking control of the head tag and inserting your own HtmlMeta you can easily customise these tags.

You might have noticed that when you create a new master page in visual studio your <head> tag gets decorated with a runat="server" attribute.

Asp.net doesn't add this kind of decoration to any other html tags (although you are free to add it if you want). So what makes the head tag special?

By adding the runat="server" you're giving actually converting the control into a HtmlHead control. That doesn't particularly matter for this tutorial other than to note that given a reference to the head control you get all the extras that come with asp.net controls such as access to its controls collection.

Why would you bother?

Neither the page meta description or meta keywords tags will do much for your sites ranking so why would you take the time to do this?

Well Google has gone on record to say that the keywords tag is not taken into account when ranking your score. Honestly I don't think its worth the effort to add the keywords into sites any more. I have seen some people give the opinion that it future proofs your site and that if Google ever does implement it into the algorithm then you will be ready. That seems like a fairly weak premise to base your decision on.

The description tag on the hand can be valuable. Perhaps not for ranking well in the search engines directly but more for the social engineering aspect. When you have get your result to appear in the search engine the text displayed from your meta description could make the difference between somebody clicking your site or your competitors.

Introducing the HtmlMeta control

The HtmlMeta control lets us wrap up <meta> tags via asp.net code. To add a meta description we need to create an instance, set the name property, the content property, and then add it to the head:

HtmlMeta meta = new HtmlMeta();
meta.Name = "description";
meta.Content = "this is a meta description tag";
head.Controls.Add(meta);

Its the exact same code for the keywords tag - you just change the name.

Public Properties

Instead of copying this code in every time you want to add meta tags to your page you can wrap these two concepts up in public properties which are easy to set.

The code would go in the code-behind file for your master page and would look something like this:

public string MetaDescription
{
    set
    {
        HtmlMeta meta = new HtmlMeta();
        meta.Name = "description";
        meta.Content = value;
        head.Controls.Add(meta);
    }
}

public string MetaKeywords
{
    set
    {
        HtmlMeta meta = new HtmlMeta();
        meta.Name = "keywords";
        meta.Content = value;
        head.Controls.Add(meta);
    }
}

If you get red squigglies under the HtmlMeta in visual studio then you have probably just forgotten to include the System.Web.UI.HtmlControls namespace that it lives in:

using System.Web.UI.HtmlControls;

Further reading

kick it on DotNetKicks.com Shout it

Using the RequiredFieldValidator attribute InitialValue to control valid selections in your DropDownLists

Posted on: Monday, 19 October 2009 18:00

The RequiredFieldValidator is a common utility in the asp.net coders validation toolkit. Its simple to use and probably represents one of the most common requirements for validation - that data must be there.

Its official definition is:

Evaluates the value of an input control to ensure that the user enters a value.

Using it to require TextBox content is an obvious and straightforward use but using it to validate DropDownList selections might not occur to you straight away.

How would you stop the user from submitting the form with "Please select" selected in the sample DropDownList below?

<asp:DropDownList ID="DropDownList1" runat="server" ValidationGroup="DropDownSample">
   <asp:ListItem>Please select</asp:ListItem>
   <asp:ListItem>Lincolnshire</asp:ListItem>
   <asp:ListItem>Nottinghamshire</asp:ListItem>
</asp:DropDownList>

InitialValue is the key. To use it you simply setup your RequiredFieldValidator as you normally would but add in the extra InitialValue attribute set to the string of text that you don't want to be submitted.

The RequiredFieldValidator for the DropDownList above would look something like this:

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" InitialValue="Please select" ControlToValidate="DropDownList1" ErrorMessage="Please select a shire" />

A Real World Databound Example

The technique above is great for ensuring that your users properly select values for your DropDownLists. In the real world however you'll usually find yourself needing to bind the data to your drop down. So the issue becomes how do you combine your initial value text with the data that's bound?

There is an attribute called AppendDataBoundItems="True" which you can add to a DropDownList. This means that when you databind your dropdown the options you have hard coded in will not be overwritten.

So if you added the first starter ListItem with the text of "Please select" and databind your DropDownList it will be preserved at the top with your data below. This means you don't have to do any special tricks to get your default text included in your data set.

In the sample below I have included a datasource which randomly generates a list of numbers. Its a good example of how to create your own bindable data objects, but its not the focus of this article.

<asp:DropDownList ID="DropDownList2" runat="server" ValidationGroup="DataBoundDropDownSample"
    AppendDataBoundItems="True" DataSourceID="ObjectDataSource1">
    <asp:ListItem>Please select</asp:ListItem>
</asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="Select" TypeName="RunTingsProper.Sample.Data.SimpleIntegerData">
</asp:ObjectDataSource>
<div>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" InitialValue="Please select"
        ControlToValidate="DropDownList2" ValidationGroup="DataBoundDropDownSample" ErrorMessage="Please select a number" /></div>
<asp:Button ID="Button2" runat="server" Text="Select" ValidationGroup="DataBoundDropDownSample" />

Download these examples

You can download these examples to play around with here:

Bonus tip - InitialValue can also be used for TextBox's

The text that you set in the InitialValue can also be used on other input controls. In theory you can use it to prevent any value that you like being entered into a TextBox. The TextBox doesn't have to have that value embedded at the start - it just can't be submitted with that value.

In practice this doesn't really come in useful very often; usually if you do need this kind of feature you can solve your problem more succinctly with a RegularExpressionValidator.

Bonus tip #2 - You can use more than one validator on a control

Don't forget that you can add more than one RequiredFieldValidator to work on a single control. This means that should you find yourself wanting to prevent more than one selection in a DropDownList you could wire up as many RequiredFieldValidators (each with their own InitialValue attributes) as you need to solve the problem.

Further Reading

kick it on DotNetKicks.com Shout it

The secret newline symbol for html encoded controls

Posted on: Sunday, 18 October 2009 18:00

ASCII Character 10 is an under loved character in the ASCII set. It lurks around there right at the beginning in the non-displayed range and most of the time you use it you don't even realise it.

Well you probably already guessed from the subject of this post that this mysterious symbol is actually the newline character.

A lot of controls automatically html encode their output, and rightly so, its asp.net's way of protecting you from cross site scripting attacks and it also makes your site much more likely to show you a green light when you post it through the w3c validator.

But sometimes you want a specific markup to be displayed. Whether its you or your boss that's the perfectionist you need that newline and your <br /> or \n have failed you.

So how do you encode the newline? ASCII 10 to the rescue!

The entity looks like this:

&#010;

and it can be used in your html encoded strings because its already html encoded!

I actually found this tip tucked away in a thread on the asp.net forums (see further reading). It was half way down the thread and it didn't even get marked as the answer! Credit where credits due - thanks for this tip Mohamed Alsakaf!

Usage Example

<asp:Button ID="Button1" runat="server" Text="An example of a&#010;long button&#010;with complete control over the newlines" />

Further Reading

kick it on DotNetKicks.com Shout it vote it on WebDevVote.com

Easy default roles for new users with the CreateUserWizard

Posted on: Saturday, 17 October 2009 14:08

Here's a scenario for you: You have an admin panel and you want to let the administrators of the site create extra admin accounts when they need to. Your site uses asp.net membership and roles and you need an easy way to make sure the new admin is added to the administrator role at creation.

To implement this on your site you only need a couple of lines of code.

  1. Open the page in your admin panel which has the CreateUserWizard in it.
  2. Make sure that you have disabled automatic login for newly created users.
  3. Single click on the CreateUserWizard in design view.
  4. Bring the properties window up by pressing F4 if its not already visible.
  5. Click the lightning rod to view the events.
  6. Double click on the CreatedUser event.
  7. Put the code from the event below into your newly created event.
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
    CreateUserWizard cuw = (CreateUserWizard)sender;

    string RoleToJoin = "Administrator";

    if (!Roles.IsUserInRole(cuw.UserName, RoleToJoin))
    {
        Roles.AddUserToRole(cuw.UserName, RoleToJoin);
    }
}

If your Roles isn't lighting up then you are missing a reference to the System.Web.Security namespace which can be added by inserting the following code into the top of your code-behind:

using System.Web.Security;
kick it on DotNetKicks.com Shout it

The sneaky Open Command Window Here feature in Windows Vista

Posted on: Friday, 16 October 2009 18:00

I am by no means the first to blog this (most people probably blogged this about three years ago when Vista came out!) but I keep using it recently and I thought maybe some people have forgotten this in the last few years.

That's often the problem with a really cool tip - if you don't keep using it then you forget it. Sometimes when you're in the middle of things you half remember it but don't know how to find the exact trick quicker than it is to do it the "hard way".

Isn't it lucky for me then that now I'll always know that this tip can be refreshed in my mind with a quick search of my blog?

For the rest of you this might be your only chance for the next three years so listen up :)

How to get a Open Command Window Here option in the context menu of a folder

To get the Command Prompt Here option you simply have to hold down the shift key and right click on your folder. The context menu that pops up looks pretty similar to the one you always get except that it has an extra entry that says "Command Prompt Here":

open-command-window-here

Bonus knowledge - network drive mapping

While researching this blog post (yes I did research for a tip this simple) I found this little tidbit over on this post:

(Reproduced entirely without permission - sorry Tim!)

What's really cool about this is that if the target folder is a network location, Windows Vista silently maps a network drive to that location before opening the folder (so that your command prompt has a valid path containing a drive letter) and then deletes the network drive once the command prompt is closed.

Source: Tim Sneath's Blog

He actually has a pretty interesting series of Vista tips if you are up for the distraction:

Yes you can have your javascript style curly brace positioning if you really want to

Posted on: Thursday, 15 October 2009 18:00

This question came up on the forums the other day. Basically somebody wanted to change the auto formatting features of Visual Studio so that their curly braces didnt get pushed down on to their own lines every time they wrote the next line.

An example of how visual studio will auto-format your methods out of the box:

public bool IsEnabled()
{
  return true;
}

However the user wanted to keep the first curly brace on the same line as the method signature like:

public bool IsEnabled() {
  return true;
}

It's a matter of personal style. Personally I think it is less readable because it reduces the scanability of the code - you have to schwip your eyes over to the end of the method signature (which can be a variable length) to check where the start of the curly braces are.

Anyway I appreciate everyone has their preferences so this is how you set it up if you are excited about this same-line curly brace option:

  1. Click Tools | Options…
  2. Scroll down to the Text Editor node
  3. Expand the C# node
  4. Expand the Formatting node
  5. Click on the New Lines node
  6. You will see a list of options like in the image below which give you full control over when Visual Studio should put your open brace on a new line

newlinesforbraces

Visual Web Developer 2008 Users

You might be wondering if this option is available to you, or you might have tried to follow the tutorial above and found out you cant find the nodes I described?

Well it is possible to configure this in VWD 2008 - the only difference is that after step 1 you need to tick the little checkbox that says "Show all settings".

An easy way to keep your dev and live server urls in sync

Posted on: Wednesday, 14 October 2009 18:00

A common setup for your live server is to run your website on the root of the domain. By this I mean if you wanted to go to the homepage of your site you would type in

http://www.example.com/

When you are working on your dev copy of the site with Cassini on localhost (the built in dev web server) though you find your urls look more like

http://localhost:4865/YourProjectName/

If you're working purely with asp.net components in your site then you can always rely on the squiggly notation (called the tilde) to ensure your urls are mapped to what is called your "Application Root".

So you could have an <asp:Image> that has an ImageUrl attribute which looks like this:

<asp:Image runat="server" ID="Image1" ImageUrl="~/Images/thumb1.gif" />

And this would get turned into the proper url(either /Images/thumb1.gif or /YourProjectName/Images/thumb1.gif).

The trouble is that in most projects you need to use some links that don't mesh into the tilde enabled mapping systems such as the urls inside your CSS files - or even linking the CSS files into your template.

If all this is sounding like a familiar problem then this tip is for you. The trick we need to perform is to make Cassini run your dev website on the root of the localhost domain rather than in a subdirectory. That way a single url can be used on both your dev and live servers.

The steps are pretty simple:

  1. In the Solution Explorer window you select your Project node
  2. In the Properties window (press F4 if you can't see it) you change the "Virtual path" attribute from /ProjectName to /

The two windows look like this in Visual Studio 2008:

how-to-change-site-root

Shout it kick it on DotNetKicks.com

I didn't want you logged in! How to prevent new users being signed in with CreateUserWizard

Posted on: Tuesday, 13 October 2009 19:55

This one has come up twice in the past week as an unknown feature of the CreateUserWizard. I've seen developers performing complicated code-behind magic to try and prevent the user being logged in and others simply asking if its possible.
The default behaviour of the CreateUserWizard is that when it has created the user it logs that new user in.
You might not want this for a few reasons:
  1. You are in an admin panel and you don't open up your signup's to the public.
  2. You have some extra coding in place that sends out a verification email before they are let into the system
  3. You want to review the accounts by hand before you activate them
  4. Some other mysterious reason

Well the way to prevent it is to add the following attribute to your CreateUserWizard control:

LoginCreatedUser="False"

Its a simple as that - when the newly created user is created they are not logged in.

Further Reading


kick it on DotNetKicks.com

Where to get an asp.net 2.0 compatible AjaxControlToolkit

Posted on: Thursday, 17 September 2009 23:01

(Updated: To include the latest controls asp.net 2.0 users are missing out on)

This is just a simple link so that I don't have to keep finding it and explaining the situation each time the topic comes up.

Asp.net 2.0 support

The AjaxControlToolkit doesn't support asp.net 2.0 any more. This means that if you are still using asp.net 2.0 then you will have to download an older release.

The last version that was released with 2.0 support was toolkit version 1.0.20229. Download it here:

Asp.net 3.5 support

If you're looking for the latest 3.5 version then I suggest heading directly to the front page of the site so that you can get the latest version. Actually this url seems to automatically redirect you to the latest version available:

But if it breaks for you in the future then use this link and click the download button in the top right:

What's missing for asp.net 2.0 users?

The following controls (at the time of writing) are missing from the older AjaxControlToolkit:

  • HTMLEditor
  • ComboBox
  • ColorPicker
  • MultiHandleSlider
  • Seadragon Image Viewer
  • AsyncFileUpload

Round off time to the nearest minute

Posted on: 07:59

Say you have a DateTime object like this:

DateTime someTime = DateTime.Parse("00:00:38");

Rounding Up

How would you round this up to the nearest minute? There isn't a built in function to do this so you have to use a little bit of maths to get there. There are 60 seconds in a minute. We already have 38 seconds on the clock. So we need to add on 60 - 38 = 22 more seconds.

In code this looks like:

DateTime RoundUp = DateTime.Parse("00:00:38");
RoundUp = RoundUp.AddSeconds(60 - RoundUp.Second);

Now our RoundUp contains "00:01:00".

Rounding Down

To round down we use the same idea:

DateTime RoundDown = DateTime.Parse("00:01:38");
RoundDown = RoundDown.AddSeconds(-RoundDown.Second);

Note

The AddSeconds() method doesn't actually alter the DateTime its working on - it just returns a new one. This is why I assigned the DateTime to itself in the examples above.

Setting a default button so your users can press enter to submit your form

Posted on: Thursday, 20 August 2009 20:03

You might have noticed that when you press enter to submit a form in your asp.net page it just refreshes the page instead of submitting as you would expect.

The reason behind this is that asp.net web forms uses the <form> html tag to power the whole postback mechanism. This means that the default behaviour of submitting the form is still occurring but as far as asp.net is concerned you have just submitted its postback form with no commands so it just refreshes.

DefaultButton property

Anyway enough of the back story. The way around this is to set the DefaultButton property. The DefaultButton property was added to the HtmlForm and Panel classes in asp.net 2.0.

You can set this programmatically:

Panel1.DefaultButton = Button1.UniqueID;

or via the code markup:

<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
</asp:Panel>

Per panel

The best use of the DefaultButton property is at the Panel level. The asp.net webforms postback model defines a single html form that all elements of the page are contained in.

If you have for example a login button and a search box in your masterpage, a feedback form in the content area then you have several logical forms contained behind the scenes in a single html form tag. Your users will expect to press enter in the search box and trigger a search. They dont want to see your feedback form validators kicking up a fuss.

By putting each logical form inside an you can set the default button to improve the user experience.

At the form level

As I have already hinted you can also do this at the page level by setting the DefaultButton on the behind-the-scenes page level form tag. As you will already see this is not a good idea for serious projects but you may want to set it in certain circumstances.

If you are in a content page of a masterpage then you will need to do it in the code behind:

this.Form.DefaultButton = this.Button1.UniqueID;

Accessibility

As an added bonus you are also improving the experience of visually impaired or otherwise disabled visitors. By defining the default button you are helping the screen reader software to have a fighting chance at understanding your asp.net page.

Gotcha - Buttons and ImageButtons only (not LinkButtons)

You can't set a <asp:LinkButton> as your DefaultButton. Technically you are supposed to be able use any control which implements IButtonControl but you cannot use the LinkButton. I think this is probably something to do with the fact that LinkButton is a javascript postback while the other buttons render out to proper form elements.

Further Reading

Using a CompareValidator to check input is a valid date

Posted on: Tuesday, 28 July 2009 23:27

The CompareValidator can do more than just compare two controls. You can also compare it against several of the main .net data types such as Date, Integer, Double and Currency.

To do this you would set Operator="DataTypeCheck" and instead of setting the ControlToCompare or ValueToCompare attributes as you normally would you use the Type="Date" (or any of the data types I have listed above).

Here is an example page which illustrates a very simple usage of it:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CompareValidatorExample._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>CompareValidator Date Validation</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            CompareValidator Date Validation</h1>
        <asp:TextBox ID="TextBox1" ValidationGroup="CompareValidatorDateTest" runat="server"></asp:TextBox>
        <asp:Button ID="ButtonSubmit" runat="server" ValidationGroup="CompareValidatorDateTest" Text="Validate Date" /><br />
        <asp:CompareValidator ID="CompareValidator1" Display="dynamic" ControlToValidate="TextBox1"
            Type="Date" Operator="DataTypeCheck" Text="Please enter a valid date" runat="server"
            ValidationGroup="CompareValidatorDateTest" />
    </div>
    </form>
</body>
</html>

The ValidationGroup attribute

Here is another little side-tip; the ValidationGroup attribute that I have spread throughout this code is a great way to avoid confusion later on when you end up with more than one group of form items in a page. If for example you have a login box in the top corner of your page then the ValidationGroup attribute will let you stop the "username required" validator firing when you click the Submit button on this example.

Advanced Validation

The CompareValidator is one of those controls that provides great basic features but quickly runs out of steam when your websites require a little bit more customisation.

Two things to watch out for when using the CompareValidator in this way is that the Date type will take the format of whatever locale the server is running in. As a UK developer I have sometimes found the server running in an American locale when I uploaded the site which flipped the month and day around.

Another caveat is currency validation - no currency symbols allowed!

To get around these limitations you have the option of using regular expressions via the RegularExpressionValidator or going all-out and developing your own validators by inheriting the base class BaseValidator.

Further Reading

Rendering the correct label tag in your forms

Posted on: Monday, 27 July 2009 18:39

You should be using combinations of <asp:Label> tags and input tags such as <asp:TextBox> in your forms.

The <asp:Label> tag is one of several controls that will render different html depending on the way you configure it. Its default is to turn into a <span> tag but in the scenario above the correct tag would be a <label> with a for="" attribute.

How do you do this? Just add the AssociatedControlID attribute to your control.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Label AssociatedControlID Example</title>
</head>
<body>
    <form id="form1" runat="server">
        <h1>Label AssociatedControlID Example</h1>
        <p>Load this page into a browser and view source to see the different html markup.</p>
        <h2>Label tag without an association</h2>
        <asp:Label ID="Label1" runat="server" AssociatedControlID="TextBox1" Text="Label" /><br />
        <asp:TextBox ID="TextBox1" runat="server" />
        <h2>Label tag with an association</h2>
        <asp:Label ID="Label2" runat="server" AssociatedControlID="TextBox2" Text="Label" /><br />
        <asp:TextBox ID="TextBox2" runat="server" />
    </form>
</body>
</html>

The benefits of this technique are two-fold. Firstly by using semantic mark-up you are staying true to the intentions of web standards. Secondly you are enhancing accessibility by giving screen readers and other devices a much better chance of matching the label with the input control.

If it isn't already - this should become a standard practice in your form development technique.

Asp.net v1.1 and older

This feature is not supported in asp.net 1.1 and older. To be a good net citizen in those versions of .net you will have to manually create a label tag and associate the for tag using inline commands such as:

<label for="<%=TextBox1.ClientID %>">Label</label>
<asp:TextBox id="TextBox1" runat="server" />