Archive for the ‘.NET’ Category

asp:label or asp:literal

August 9, 2007

One of the issues I hear raised with ASP.NET is that it doesn’t produce valid XHTML code. In some cases, it is true that it’s hard, if not impossible, to do so. In other cases, there are simple things we can do that greatly improve the quality of HTML code from our applications. One of the easiest things is to follow the advice of Phil Haack in “ASP.NET Tip - Use the Label Control Correctly” when he says “Never use the ASP.NET label control when a Literal would do.

Consider the following lines of ASP.NET Code:

<p><asp:Label ID="lblTest" runat="server">This is a label</asp:Label></p>
<p><asp:Literal ID="litTest" runat="server">This is a literal</asp:Literal></p>

This produces the HTML code:

<p><span id="ctl00_ContentPlaceHolder1_lblTest">This is a label</span></p>
<p>This is a literal</p>

The <asp:Label> tag produced an extra <span> tag while the <asp:Literal> tag did not. This is the only real difference when the tags are used in this way. You can easily interact with either of these tags in the code behind file to assign additional, or completely different, text to the tags, so in that respect, they are completely interchangeable.

Whenever I modify an existing page that uses <asp:Label> tags, I evaluate whether to change them to <asp:Literal>. In most cases, it only takes a few minutes to make this change. When doing new pages, I always use choose <asp:Literal> over <asp:Label> whenever it will work. In doing so, the application outputs cleaner HTML.

Adding CSS to a Single Page

July 30, 2007

The project I’m working on has a page with an input form, and I  want to use CSS to format the form. Options for locating these styles include adding them in the main stylesheet used by the project, adding an embedded stylesheet to the page, creating a new CSS file and adding it to the master page, or creating a new CSS file and adding it to the page with the form.

I decided to create the CSS file and link it only page with the input form. In this project, linking to an additional CSS file is easier to implement than embedded styles, and should be easier to maintain in the long run. Adding styles to the main CSS file or linking from master file would mean that all the pages in the project would get the extra styles, not just the one that has the form.

This project is being developed in .NET, and is taking advantage of master files (a cool feature added in .NET 2.0) The <HEAD> section of the input form is coming from the master file, therefore I can’t simply add the link in .aspx file here. It has to be linked though the backend code. To do this, I added the following code to the Page_Load function:

// Add a CSS file to handle the formatting of the form
HtmlLink cssLink = new HtmlLink();

cssLink.href="/grainstorage/styles/form.css";
cssLink.Attributes.Add("rel", "stylesheet");
cssLink.Attributes.Add("type", "text/css");
Header.Controls.Add(cssLink);

This code builds the link with the proper information, then adds it to the header of the page at runtime. Works like a charm when you have a stylesheet that only affects a few pages in your project.

Connecting JavaScript with a TextBox

July 26, 2007

Yesterday I was working on a web application where we wanted to have a JavaScript function run when the user changes a TextBox. It was a simple function, which took three input values and performs calculations to generate two additional values. I soon discovered two issues when working with JavaScript in ASP.NET. The first is that the TextBox control is server-side, so it doesn’t include the client-side “onclick” attribute. Second, is that when .NET generates the input box, it adds the ID of the parent container to the ID of the TextBox, for example ID=”TextBox1″ may become ID=”ctl00_ContentPlaceHolder1_TextBox1″.

Doing an Internet search, I found two solutions to the first issue. One option is to include the attribute onchange=”myJavaScriptFunction()” in the TextBox control. Visual Studio will give you a warning, but it does work. The second option is to include the following line of code in the Page_ Load function:

TextBox1.Attributes.Add("onchange", "myJavaScriptFunction()");

I prefer this method because Visual Studio doesn’t flag it.

To solve the second issue, I found an example where they used the ClientID attribute of the TextBox Control to find the element in JavaScript. Here is a sample JavaScript Function that does a popup alert, giving the value that was entered in TextBox1:

function myJavaScriptFunction()
{
  var myField = document.getElementById("<%= TextBox1.ClientID %>");

  alert(myField.value);
}

This is a kind of ugly, but it works. You can create as many variables as you need to point to your .NET controls. The function I wrote yesterday had 5 of these temporary variables. Seems like a lot of work to assign values to a couple readonly fields in the form.

Validation Groups

July 23, 2007

A cool feature of the validation controls in .NET is the property “ValidationGroup”. With this property, you can easily activate different validation controls based on which button is clicked.

For example, suppose you have a content page that has a search box. In addition, this page has a feedback form at the bottom of the page where you can rate “Was this page useful” from 1 to 5. The requirement for this page is that if you click on the search button, you must have entered a search term, and if you click on the rate page button, you must have selected a numerical rating.

To do this, you would add a required field validator for each of these of these fields. However when you test this page, you discover that when you click on the search button, it complains that you didn’t select a page rating, and when you click to page rating button it complains that you didn’t enter a search term. How do you get around this?

Use the ValidationGroup property. In the validation control for the search term text box and the search button, set the property ValidationGroup =”search”, and in the validation control for the page rating entry field and the page rating button set the property ValidationGroup=”pagerating”. This way, when you click the search button, it only runs the validation controls that have ValidationGroup=”search”, and it will not complain that there is not a page rating entered. Likewise with the page rating button.

Server-Side Validation

July 19, 2007

A couple of weeks ago, I was talking to someone who is doing a project for us. He is fairly new to .NET programming, so when I told him that I wanted both server-side and client-side validation, it scared him a little bit.

He knew how to do client-side validation using the built-in validation controls in ASP.NET. This is fairly easy to do. You put the validation control into your aspx file, and connect it to the control you want to validate. Then ASP.NET will include the required JavaScript for the client to do validation. The problem is that this JavaScript doesn’t run if the client has JavaScript turned off, or if the client doesn’t support JavaScript.

He thought he’d have to write the code to do the server-side validation. He wasn’t aware that you could use .NET’s validation controls on the server-side as well as client-side. All you need to do is add the following code to the beginning of your button handler:

if (!Page.IsValid)
{
    return;
}

This cause the server-side to run through the validation controls. If any fail, then you return to web page, which will now include the error messages from your validation controls. If all the validation controls pass, then it will go on to the next line in the button handler.

It really is this easy to include server-side validation in ASP.NET!

Application Settings

July 17, 2007

Yesterday, I wrote about wrapping your session state variables into a class. The same thing can be done with other variables such as application settings and connection strings. For this class I normally name the class MySettings.

The code for doing this is very similar to yesterdays code.

public static string mailFrom
{
    get { return ConfigurationManager.AppSettings["MailFrom"].ToString(); }
}
public static string calendarConnectionString
{
    get { return ConfigurationManager.ConnectionStrings["Test"].ToString(); }
}

As with yesterdays examples, it is then very easy to use these applications settings. When you want to use these settings you’d write one of the following:

MySettings.calendarConnectionString
MySettings.mailFrom

Again, this extra class will add a few extra lines of code to your project. However, in the long run it will save you time and effort when you later decide to change something. For example, “Test” is not a good name to call your connection string, so you may want to change it to “CalendarDatabase”. Using this technique, you would change it in your web.config file and in this class, and you’re done. Without this class, you would need to find and replace in your entire source code for the application. What happens when you miss one?

Another advantage of implementing your application settings this way is that Visual Studio’s IntelliSense works with it. I really like IntelliSense!

Wrapping Session States

July 16, 2007

A common way of using session states in ASP.NET is to simply use the Session object in your code behind file, for example you might say:

Session["MyFirstName"] = “Brian”;
Session["MyAge"] = “24″;        // Not my real age :-) 

Another option would be to wrap these Session states into a class. You’d do this by creating the class, I usually name this class “MySession”, with code that looks like this:

public static string firstName    {
get { return HttpContext.Current.Session["MyFirstName"].ToString(); }
set { HttpContext.Current.Session["MyFirstName"] = value; }
}
public static int age    {
get { return Convert.ToInt32(HttpContext.Current.Session["MyAge"].ToString()); }
set { HttpContext.Current.Session["MyAge"] = value; }
}

This give you a few advantages:

  1. You now have all your session states located in a single file in source code.
  2. You access the session states using the MySession.firstName and MySession.age
  3. Because you are using a class, IntelliSense now works! You don’t have to remember that the session state name was “MyFirstName”. All you need to remember is MySession. Visual Studio will give you the rest.
  4. Strongly typed session states. Notice that the type of MySession.age is an integer. It will throw an exception if you try to assign it a value of a different type.

Wrapping your session states into a class may add a little to the number of lines that you write. In the long run, however, it will likely save you time because you will always know what session states are available to you in your application. No more trying to remember what you named it 6 months ago when you are asked to make a change to the application.

I’ve used this technique in a number of projects, and it has worked well. Thanks to Paul Sheriff for sharing this tip when presenting at the Iowa Dot Net Users Group.