Tuesday, 28 July 2009

Using a CompareValidator to check input is a valid date

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

Monday, 27 July 2009

The name 'xxx' Does Not Exist in the Current Context

If you get this error when you are compiling then one thing that it might be is two aspx files pointing at one code behind file.

If you created your new page by doing a file > save as instead of using add new item then you are very likely to have unwittingly walked into this trap.

By default asp.net web pages come in pairs; an aspx file and a codebehind (either aspx.cs or aspx.vb depending on the language used).

When you did a file > save as only the .aspx file was duplicated and both point at the original aspx.cs / aspx.vb file!

The solution

To solve this problem you need to create a new file using the proper add item dialog (found in Project > Add New Item). You can copy over the aspx mark-up from your broken page if need to but make sure that you don't bring the broken @Page declaration with it or you will just point it back at the same code behind again!

If it has taken you a while to notice this error you may also have to extract any events that you have handled in the code behind.

Rendering the correct label tag in your forms

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" />

Sunday, 26 July 2009

Basic PayPal integration using a HTTP GET request

To add a simple PayPal button to your website you could use some code like this:

        // Variables
        string business = "youremail@example.com";
        string item_name = "Screwdriver set";
        string item_number = "1054b";
        decimal amount = 10.99m;
 
        // Build the PayPal url
        StringBuilder sb = new StringBuilder();
        sb.Append("cmd=_xclick");
        sb.Append("&business=" + HttpUtility.UrlEncode(business));
        sb.Append("&no_shipping=1");
        sb.Append("&currency_code=GBP");
        sb.Append("&lc=GB");
        sb.Append("&bn=PP-BuyNowBF");
        sb.Append("&item_name=" + HttpUtility.UrlEncode(item_name));
        sb.Append("&item_number=" + HttpUtility.UrlEncode(item_number));
        sb.Append("&amount=" + HttpUtility.UrlEncode(amount.ToString()));

        // Redirect to PayPal to make secure payment
        Response.Redirect(@"https://www.paypal.com/cgi-bin/webscr?" + sb.ToString());

Depending on the country you are using PayPal in you may have to change the lc and currency_code lines.

Put this in a button click event on your page, customise the variables as required and you're all set!

Burn! kick it Shout it

Where can I get Microsoft SQL Server Management Studio Express 2008 from?

Direct Download

Microsoft have now updated their download page so that you can download the Microsoft SQL Server Management Studio Express as an individual download.

Visit this website:

Scroll down to the "Other Installation Options" section and you will see that at the bottom of the column titled "Management Tools" there is a Install link.

Microsoft Web Platform

You can also get the application via the Microsoft Web Platform Installer which can be downloaded here:

Backup your database using an SQL command (Export to .bak)

This article has been updated and published on CodeAsp.Net

You can read it here:

Saturday, 25 July 2009

Ordered lists don't display correctly in the Blogger.com “Tic Tac” template

I don’t know where you’re reading this information from now, but this blog originally used blogger.com and started out with the Tic Tac template.

If you are a non technical user this might clear up why your Ordered lists (IE lists with 1, 2, 3, etc for bullet points) are displaying as orange tic tacs.

  1. You have to login to your blog and click the Layout template.
  2. Then click the Edit Html sub menu button.
  3. Scroll down the the line that says /* unordered list style */
  4. Find the CSS rule that applies to li (hint: its a couple of lines further down)
  5. Change the li to ul li
  6. Save your changes

Now when you view an ordered list you will see proper numbered bullet points.

If you are using Windows Live Writer to post your blog items (as I am) then you will also have to follow these steps within the Windows Live Writer application to get your template to display numbers while you are writing it:

  1. Select the blog you are using the (newly updated) Tic Tac theme with
  2. Click the Blogs menu
  3. Choose Edit blog settings…
  4. Click the Editing tab down the left hand side
  5. Click the Refresh Theme button
  6. Marvel as your posts now have numbers on them while being edited

Backup your database using Microsoft SQL Server Management Studio Express (Export to .bak)

This article has been updated and published on CodeAsp.Net

You can read it here:

Converting an Enum to its string representation

I inherited a particularly nasty piece of legacy code and in the process of wrapping it into a cleaner interface I decided to use an enum as a parameter rather than a string. The reason was that strings are bad anyway but this particular bit of code was case sensitive as well.

If you have used an enum before you will know that it can represent numbers (usually int but also byte, sbyte, short, ushort, int, uint, long, and ulong) but not strings.

I created my enum and I was in the process of coding up a lookup table to convert my enum parameter back into a string when I found this handy method called Enum.GetName().

Using this method I can turn the enum constant into a string representation of itself.

Taking the enum:

using System;

// declares the enum
public enum OvenTemperature
{
    Low,
    Medium,
    High
}

I can then use this code to turn OvenTemperature.Low into the string “Low”:

// declare an instance of the enum
OvenTemperature ovenTemp = OvenTemperature.Low;

// convert its value to a string
string convertedOutput = Enum.GetName(typeof(OvenTemperature), ovenTemp);

// convertedOutput now equals "Low"

This solution only works if you need your string representation of the enum to be the exact same word that you use as the enum constant but when this situation arises it saves you having to maintain a separate lookup table for the conversion.

Complete sample console application

using System;

namespace ConvertEnumToStringRepresentation
{
    // declares the enum
    public enum OvenTemperature
    {
        Low,
        Medium,
        High
    }

    class ConvertEnumToStringRepresentationProgram
    {
        static void Main(string[] args)
        {
            // declare an instance of the enum
            OvenTemperature ovenTemp = OvenTemperature.Low;

            // convert its value to a string
            string convertedOutput = Enum.GetName(typeof(OvenTemperature), ovenTemp);

            // convertedOutput now equals "Low"
            Console.WriteLine("convertedOutput = " + convertedOutput);

            // pause execution so the example can be seen
            Console.ReadLine();
        }
    }
}

-->