Creating a Composite Control in ASP.NET

Have you read my other post on custom controls?

A composite control is a custom web control that contains other web server controls. A composite control inherits from the CompositeControl class. You add constituent controls to this control. The composite control handles events raised by its child controls.

A composite control is rendered as a tree of constituent control, each having its own life cycle. Together, these constituent controls form a new control. Because each of the child controls handles its own ViewState and postback data, you don’t need to write extra code to deal with this.

To create a composite control, you start by creating a class that inherits from the CompositeControl class and overrides the CreateChildControls method. The CreateChildControls method contains the code to instantiate the child controls and set their properties.

For the example of this post I will create a composite control that have a label, a textbox and a submit button.

image

In this code the Name property is exposed to the developer using the control. An event called Submitted is also created so that users of the control can receive notification when the Submit button’s click event fires. The result of this control is the following.

image

And you can catch the Submitted event on the page like this.

image

image

The end result is the following.

image

Creating a Custom Web Server Control in ASP.NET using Visual Studio 2010

You can read my other blog post about custom user controls if you are more interested in that type of custom controls.

A custom web control is a control that you write that inherits either from the WebControl class or from an existing web server control, e.g the Textbox control in ASP.NET. Each custom control contains the code necessary to render the control. The control can be compiled to a DLL file that can be shared among applications.

There is two ways of creating a custom web control, the first is to inherit from a existing web server control and extend its functionality. The second is to inherit from the WebControl class which provides a base set of functionality. With this functionality you can handle styles such as BackColor and so on.

Inherit from an Existing ASP.NET Web Server Control

As an example of this approach lets create a custom web server control that will inherit from the Textbox control, and let the developer add a label to the textbox. This control can later be used on all pages that need a textbox with a label.

The first step when creating a custom web server control is to decide how to develop it. I have chosen to create my control in a new ASP.NET Server Control project in Visual Studio. This approach gives us the ability to build our control as a DLL an share it with other applications. As you will se when the first class added to this project will contain a template of a custom web server control with a quite a few attributes set to the class, property and method, this will be explained later in this post.

After adding a new class and set it to inherit from the TextBox class. You also need to reference the System.Web and System.Web.UI.WebControls.

image

For the label part of our custom web server control we need one property of type string that will be used as the label text.

image

The next step is to override a method from the TextBox class called Render. In this method we will add the rendering for the label. And at the end we call the base.Render() method to actually render the HTML of the inherited TextBox control.

image

This control is almost finished, the only thing left to do is to provide the LabelText property with ViewState support. To do this you just change the get and set of the property to the following.

image

And the rendered control will look like this.

image

 

Inheriting Directly from the WebControl Class

Another approach to creating a custom web control is to create a control that inherits directly from the WebControl class. This is preferable when there is no existing control that provides enough default behavior similar to the control you want to implement. When inheriting from the WebControl class you, typically override the Render method to provide the HTML output you want for your control. How ever there is other Render methods shown below.

  • Render
    You can use the Render method when you want to control all output of your control’s HTML to the client.
  • RenderContents
    You use this method to ensure that the HTML for your control is rendered between the appropriate begin and end HTML tags. When Render is called on your control, it will call three methods in a sequence: RenderBeginTag, RenderContent, and RenderEndTag.
  • RenderBeginTag and RenderEndTag
    These methods are used to render HTML both at the beginning of a control listing and at the end. You override these methods when creating custom controls that display multiple controls between opening and closing tags.
  • RenderChildren
    If your custom control has child controls inside its ControlCollection, you can call this method to ensure that each is rendered as part of the HTML output.

The following is a short example of how to create a control inheriting from WebControl.

image

The HTML markup generated by this control is the following.

image

 

 

Adding a Custom Web Server Control to a Web Application

So far you have built a labeled textbox control, now lets see how we can add it to a web application project. In addition to use a custom web server control your project needs to reference it. If you develop your controls in the same solution you can right click the References and select Add Reference…

image 

Select the project under the Project tab, and click Ok

image

When you build your project a copy of the DLL will be placed in your web application’s bin folder.

If share your control as a DLL assembly you can right-click the References in your project, select Add References and select the Browse tab instead.

image

Browse to the DLL file, select it and click Ok. A copy of the DLL will be placed in your web applications bin folder when you build the project.

Now you need to reference the assembly and namespace for the pages that will be using your new control. To do this either add the @ Register directive in the top of your page, like this.

image

Or if you want all pages to have a reference to the control you can set a reference in the Web.config file.

image

To add the control to a page all you have to do is add a the markup for the control as you do with any other controls you use.

image

 

Visual Studio Tools Support for your Control

If you have a control that you distribute to other developers it will be a nice thing to set some additional attributes on your control that will make it easier for the users of your control to use it. Visual Studio supports a lot of attributes that will let the developers using your control to be more productive.

Adding Toolbox Support for your Custom Web Server Control

To add a control to the Toolbox window, the developer must use the Choose Toolbox Items dialog. This can be found under the Tools menu or by right click the Toolbox window.

image

In this window the user can Browse the DLL of the custom web server control and click Ok. This will add the custom control to the list in the .NET Framework Components tab.

image

Hit Ok and the control is now visible in the Toolbox window in Visual Studio.

image

Defining a Custom Icon for Your Control

The default icon displayed on the left side of your control in the Toolbox window can be customized. To do this you add the ToolboxBitmap attribute, which is contained in the System.Drawing namespace, to you custom control class. This attribute allows you to specify a path to your custom icon.

Add a bitmap icon with the size 16*16 pixels. You can right-click your ASP.NET Server Control project and select Add New Item…, then select Bitmap. Now you can create your own custom bitmap icon from within Visual Studio. Remember to resize it to 16*16 pixels thou.

There is one more thing you need to do with your bitmap file. In the properties, for the Build Action select Embedded Resource.

image

This will ensure the icon is a part of the DLL and you do not have to have a copy of the bitmap itself when sharing your custom web server control with others.

Now add the ToolboxBitmap attribute on your custom control class, pass in the type of your control and the path to the icon.

image

You might have to re-add the control to the Toolbox window to get it to show properly, but when that is done it will be as beautiful as this shows.

image

Providing a Default Property for your Custom Web Server Control

You can specify a default property for your control that will be focused in the Properties windows when the user selects the property in Visual Studio designer. As in the example used throughout this it as the key property of LabelText that I would like to have focus on when the developer views the Properties window for the control.

To accomplish this all you have to do is add the DefaultProperty attribute, which is contained in the System.ComponentModel namespace, to the custom control class and pass in the property name as a string you want to focus on.

image

Now when viewing the properties the LabelText property will be in focus.

image

Defining Attributes for Your Control Properties

There are several attributes you can apply to the properties of your control to change how those properties are managed by Visual Studio. The following lists these attributes.

  • Bindable
    The Bindable property indicate whether a control’s property should be bound to data. Setting this value to Bindable(true), the property will be displayed in the DataBindings section of the property grid in Visual Studio. The default is Bindable(false).
  • Category
    You use the Category attribute to indicate the category (or group) in which the property should be displayed in the Properties window grid when a developer changes the Properties view to Categorized. As you can se in the previous example when using the DefaultProperty attribute the default category is Misc.
  • Description
    Use the Description attribute to provide a brief description of your property’s usage. This description is shown in the bottom of the Properties pane in Visual Studio when the property is selected.
  • DefaultValue
    You use the DefaultValue attribute to set a default value for your property.
  • Localizable
    You use the Localizable attribute to indicate whether your property should (or can) be localized. Setting Localizable(true) indicates that the property should be serialized as a localized resource.

The following code shows an example of applying some of these properties to the LabelText property of the LabeledTextbox control.

image

When viewing the Properties window it looks like the following.

image

Controlling the Markup Generated for Your Custom Web Server Control

When a built-in ASP.NET control is dropped onto the webpage it generates some code in the markup. The same does your custom web server control, and the code generated cam be controlled by setting the ToolboxData attribute, which is contained in the System.Web.UI namespace, on the control class.

The following is an example of the ToolboxData attribute added to the LabeledTextbox control.

image

Notice that the {0} placeholder contains the namespace prefix as defined by the webpage designer. The generated markup looks like this.

image

You can also provide the namespace prefix that is assigned to your control by the webpage designer by assigning the TagPrefixAttribute of the System.Web.UI namespace to the assembly that contains your custom control. To do so, add the attribute declaration to the AssemblyInfo class file in your control.

image

This will generate the following markup.

image

image

Creating a Custom Designer for your Custom Web Server

When working with controls in the design view, sometimes you want to alter the default rendering of the control. You might want to show a error message if some property is invalid for example. To do so, start by adding a reference to the System.Design.dll assembly in your custom server control. You then create a new class in you user control that inherits from the ControlDesigner class. This class will override the GetDesignTimeHtml method of the ControlDesigner class to render separate design-time HTML that can be set based on the property settings of the control instance. You then apply the Designer attribute to your control. To this, you pass an instance of your ControlDesigner class.

For example, lets say you want a error message to be showed if the developer have not specified the LabelText property in the LabeledTextbox control.

image

After this class is created, you can assign the DesignerAttribute to the user control class, as shown in the following code.

image

The result in the designer is the following.

image

 

Update

I’v added the source code for this post as a downloadable zip file.

Download the source here

 

 

 

 

 

 

 

Creating a Templated User Control

This is a follow up post on my previous post about user controls and the examples in this post is a continuation on the previous, so I recommend you read that before you begin reading this.

In the previous example I created the AddressControl with a static HTML table that dictated the layout of the fields for the control. Now, lets say you want other developers who use your control to specify how the fields in the controls should be presented. This is where you can use templated user control. Setting up your user control to use a template.

  1. Start by adding a user control file to you web application
  2. Add an ASP.NET PlaceHolder control to the user control’s markup. This is the placeholder for the templated layout. This control will be exposed as a property.

    image

  3. Create a class file that will serve as a naming container for your control. A naming container is simply a control container that allows you to search for a contained child control by using FindControl. This class will inherit from Control and implement the INamingContainer interface. It should also contain public properties for any data elements.

    image

  4. In your user control’s code-behind file, implement a property of type ITemplate. This property will serve as the template for users of your control and exposes the placeholder. The name you give this property is the name used for the template tag in any consuming page’s markup.
    Apply the TemplateContainerAttribute to the ITemplate property; this marks the property as a template. To this attribute, pass the type of the naming container class for binding data as an argument of the constructor. This serves to allow binding between the container and the template definition markup when the user control is added to a page.
    Also apply the PersistenceModeAttribute to the ITemplate property. You pass the enumeration value of PersistenceMode.InnerProperty into the attribute’s constructor.

    image

  5. Add code to the Page_Init method of the user control. Here you test for the ITemplate property. If the ITemplate property is set, you create an instance of the naming container class and create an instance of the template in the naming container. You then add the naming container instance to the Controls collection of the PlaceHolder server control.

    image

  6. You might also need to pass data from your user control to the naming container. This allows users to set the properties of your user control, and use them in the container. For these situations, you must define this data in your user control as properties that a developer who is using your user control can set. You then must pass a reference to this data to the naming container. This ensures that the naming container is updated when the property values changes on the user control. In this case the naming container class would look like the following.

    image

    And in the user control’s code-behind file you would pass in the values to the AddressControlTemplateNamingContainer constructor.

    image

Using the Templated User Control

Just add a reference to the user control on the top of the page.

image

You then define the template for your control’s layout. This is done in the <LayoutTemplate> tag that was defined with the ITemplate property.

image

And you are finished, now you you’re the users of your control can set the layout of the control as they see fit.

Creating User Controls in ASP.NET

User controls are a great way of encapsulate functionality and reuse it in other places and conform to the DRY principle. You can have one or more controls in a user control and define properties, events and methods to the user control. A custom user control inherit from the UserControl class. A user control in ASP.NET is designed the same way normal pages is design, except a user control have @ Control directive at the top of the file and with the .ascx extension.

For the example of this post I will create a address user control. The following code shows the markup source of the user control.

image

 

Properties in a User Control

Often the developer need to configure the user control in some way, like passing the current user id. To allow this kind of functionality you can define properties on a user control. This properties can be set in the markup of the page where the user control is added, or in the page’s code-behind file. For this example we need two properties UserId and AddressType.

image

If you want to access the controls in a user control you need to expose each of those controls you want to access thru a property. This is because controls in a user control are declared as protected members of the control. This means they can not be accessed outside of the user control. If it is not absolutely necessary to expose the entire control then you should only expose its value. To expose the controls value in the address control you add the following properties to you user control code behind file.

image

 

Defining User Control Evens

A user control have the same events as a normal Page and are called in sync with the events on the page. For example. after the page Init event is called, the control’s Init event is called in turn. A user control can also cause a postback for the webpage to which they belong. When a user control causes a postback, its events are raised accordingly along with the events of the page. The event handlers for a user control are typically encapsulated in the particular user control. This to ensure the independent use of the control.

For example, lets say I want to find out the city based on the postal code. To do this we add a TextChanged event on the TextboxPostalCode control.

image

Then we need to make a change to the TextboxPostalCode control in the markup.

image

 

Passing Events Up to the Page

Sometimes you want a event caused by the control to be handled by the Page. For this to work you need to create a custom event argument class for your control that inherit from the EventArgs class. Lets change the previous example and let the page handle the event caused by the TextboxPostalCode control. First lets create a event argument class. In this example we pass all values, so the developer using our user control can decide what information she needs to handle the event.

image

Next step is to add code that declares an event to the user control’s class. Then you add code that handles the Textbox TextChanged event. Inside the TextChanged event, you raise your event back to the consuming page.

image

The last thing to do is to capture the event in the page using the control.

image

 

Adding a User Control to a Page

To add a user control to a page there is two things you need to do. First you need to reference it in a @ Register directive just under the @ Page directive like the following example shows.

image

Then you just add it as any other control you use, except that you use uc1 as a prefix and AddressControl as the control name.

image

You can also register a control in the Web.config file as the following example shows.

image

There is one more way of adding a control to a page, that is to dynamically add it in runtime. To do so you first create a new instance of the control by using the Page.LoadControl method and pass in the path to the control file. next you just add it to the Form or a Panel control using the Controls.Add method. To following example shows you how.

image

Now lets add a new AddressControl to the pnlWorkControl Panel.

image

And the final result of this looks like this:

image

Creating Accessible websites in ASP.NET and why you should always do it

Accessibility in web development is a great thing for three reasons, it lets users that uses a screen reader, cant use a mouse and keyboard in a normal way or use some other technology to access a webpage, use your website, it also make it easier for people with a normal mouse and keyboard to use your website, and the last great thing about it it is very easy to implement.

Basically there is two major accessibility guide lines, there is the Web Content Accessibility Guidelines (WCAG) by the World Wide Web Consortium, and there is the Section 508 of the Rehabilitation Act by the United States government. Both are supported by Visual Studio.

ASP.NET Controls and Accessibility

ASP.NET controls are design to support accessibility, for example, the controls Login, ChangePassword, PasswordRecovery and CreateUserWizard use text boxes with associated labels.

Another way ASP.NET controls support accessibility is by allowing users to skip link text. Screen readers typically read the text of links from the top to the bottom of a page. Controls such as CreateUserWizard, Menu, SiteMapPath, TreeView and Wizard support the SkipLinkText property which allow the screen reader to skip past the links.

The principals of good Visual Accessibility

The following bullets lists some good practices when creating accessible websites.

  • Describe every image by using the AlternateText property to provide alternative text.
    If you want a longer description of a image, you can use the Image controls DescriptionUrl property and pass a URL to a HTML page that describes the image. For unimportant images you can set the Image.GenerateEmptyAlternateText property to True. This will tell screen readers to ignore the image.
  • Use solid colors for background, and use contrasting colors for text.
    This is a good practice for all users, and users who might not be able to perceive low-contrast text will appreciate this much.
  • Create a flexible page layout that scales correctly when text size is increased.
    Many browsers today allow you to increase text size. Be sure that your layout do not break if text size is increased.
  • Set the Table.Caption property to a description of the table.
    Screen readers can read the Table.Caption (generates the title attribute in a HTML table), and is able to tell the purpose of the date in the table. The ASP.NET controls that support the Caption property include Table, Calendar, DetailsView, FormView and GridView.
  • Provide a way to identify column headers.
    You can create table headers by using the TableHeaderRow class and setting the TableSection property to the TableHeader enumeration of the TableRowSection class, and thus render a <thead> element. When you create cells in with the TableCell control, your can set each AssociatedHeaderCellID property for the cell to the ID of a table header cell. This causes the cell to render a header attribute that associates the cell with the corresponding column heading. Controls that support this include Calendar, DetailsView, FormView and GridView.
  • Avoid defining specific font sizes.
    Use HTML heading tags such as <H1>, <H2> and <H3> instead of font sizes to support the user’s formatting options.
  • Avoid requiring client scripts.
    Not all assistive technologies can render client scripts, so you should use client script only for nonessential effects. For example the Validation control, you can set the EnableClientScript property to false to improve accessibility. Although I would not prefer this approach. It is a huge benefit to get the error message without a pustback call for users who do not use a screen reader.

Accessibility and User Input Forms

There is some guidance you need to comply with for input forms when developing a accessibly website. ASP.NET help you with it.

  • Set the DefaultFocus property for a form to place the cursor in the logical location where data entry begins.
  • Define the tab order in a logical way so the user can use the tab key to move to the next field.
    Use the controls TabIndex property to specify the tab order for the controls.
  • Specify default buttons for forms and Panel controls by setting the DefaultButton.
    When the user press the Enter key the DefaultButton property is used to handle which button will be "clicked”.
  • Provide useful link text.
    Just use common sense for link text. This is good for not only users who uses a screen reader but simplify for all users.
  • Define access keys for button controls by setting the AccessKey property.
    Just like desktop application you can set access keys for buttons and input fields. In ASP.NET you specify the AccessKey property with a character or number and the user can press Alt + Access key. To set the focus on the control.
  • Use Label controls and the AccosiatedControlID property to define access keys for textboxes.
    If you want a access key to set focus on a textbox you need to add a Label control with the AssociatedControlID property set to the ID of the textbox and then specify the access key on the Label control.
  • Specifying meaningful error messages in the Text and ErrorMessage properties of validator controls.
    As with the link text, a meaningful error message is useful for users with screen readers.
  • Use the Panel control to create subdivisions in a form, and define the Panel.GroupingText property with a description of the controls in that panel.
    Panels in ASP.NET uses the GroupingText property to create <fieldset> and <legend> HTML elements.

The following is a example of a good input form that is fully accessibly.

image

This will generate the following HTML output.

image

 

Testing Accessibility in Visual Studio

Visual Studio can test webpages or entire web applications for compliance with WCAG and Section 508 standards. To do this you do the following. In the Solution Explorer right click the page you want to test and select Check Accessibility… Then just press the Validate button.

image

And a list of warnings will be showed in the Error List window, if your page is not compliant with the selected standards you validated against.

image

You can also validate your entire web application in Visual Studio. The process is the same as for single page validation except you select Check Accessibility… from the Tools menu.

 

Accessibility is very easy to implement and should be in the back of your head every time you create a website. It is not only good for people with different input devices and screen readers but for all users who uses your website.

Writing Globalized and Localized web applications in ASP.NET

When starting on a new web site project it is always a good idée to thing thru your globalization support strategy. Many times the customer sais the application will only be used in a single language and therefor do not need to implement support for multiple languages and cultures. But after a while the same customer comes back with new requirements that one additional language should be supported. If you have not implemented support for globalization and localization from the start you are in for some time consuming work. So it is a good way to implement support for multiple languages from the start, even if it is not in the road map to use it.

ASP.NET Resources

ASP.NET has two kind of resources, local and global. The local resource file is used on a single page only. While the global resources are shared across the entire site. A resource file is a simple XML file that allows you as a developer to externalize all globalization. This is a good thing because translator for example can just change the XML file using a XML editor and do not need to know anything about coding.

The resource file stores all strings in a data element under the root element. Where the name attribute is the key and the value element contains the current string.

<root>
<data name="AboutString" xml:space="preserve">
   <value>About</value>
</data>
</root>

Resource files uses a naming convention to support different languages and cultures. This naming convention is as follows.

  • filename.resx
  • filename.<languageid>.resx
  • filename.<languageid>-<cultureid>.resx

The first item in the list is the default resource file, this means that if the application do not have a localized version of the users language and culture it fill fall back to the default resources. The second item is a resource file for a specific language. So for example if I have a resource file Default.aspx.es.resx this file will be used for both Spanish speaking people in Spain and Spanish speaking people in Mexico. On the other hand have a resource file named Default.aspx.es-mx.resx this will be used for Spanish speaking people in Mexico, and for the Spanish visitors they will be seeing resources stored in Default.aspx.resx and the rest of the the world will use Default.aspx.resx.

Specifying the Language and Culture to use

ASP.NET automatically set what languageid and cultureid a user have based on the users browser setting or system settings. So you do not need to do anything manually. But lets say your users are using a web browser with another language setting and want to manually change the language of the website. Luckily there are a ways to of doing just that.

There are two properties in the Page class you can change.

  • Page.UICulture – This property takes a string representation of a languageid and cultureid (languageid-cultureid) use it to specify which language and culture the user have. This only specify the which global or local resources are to be loaded for the page.
  • Page.Culture – This property takes a string representation of a languageid use it to specify which language and culture the user have. This specify the date, number and currency formatting.

To programmatically set this properties you can override the InitializeCulture method in the Page class.

image

If you are using master pages, you would want to create a new Page Base class derived from the Page class and override the method in the new base class. This way you only need to write the code once. Then use it in all your pages. This is because the MasterPage class do not have a InitializeCulture method.

You can also specify the Culture and UICulture on the page level by declare it in the @ Page directive.

image

And to specify it on the site level you can specify it in the Web.config file.

image

 

Using Local Resource Files

All local resource files are stored in the ASP.NET specific folder called App_LocalResoruces, this folder can live in the root of your project or you can have one in each subfolder of your project. As said above a local resource file is connected to a single web page file in you project. This connection is by a naming convention as described also above.

You can attach controls and resources implicit by using a the meta:resourcekey attribute on your controls. For example.

image

This will tell ASP.NET that a resourcekey named ButtonString is connected to the SubmitButton control. Now because this is a implicit attach you can use the Text and ToolTip properties of the button control to specify different texts for those button properties inside the resource file.

image 

To explicitly attach resources to the button you do the following.

image

And the resource file will now look like this.

image

As you can see the use of implicit attach is a better approach, the draw down is it can not be used for global resources. When using global resources you need to use explicit attach.

If you want to localize text outside of controls in you web page you can use the ASP.NET control Localize.

image

The same here as in the button example. You have a implicit attach of the resource and need to use the Localize.Text property in the resource file.

image

Accessing local resources programmatically

You can also attach localized strings to a control property programmatically. To do this for local resources you use the GetLocalResourceObject method.

image

 

Using Global Resources

Global resources are like local resources except they are shared for the entire site. They are stored in the ASP.NET specific App_GlobalResources folder in the root of your website project. Another difference is that when attaching a global resource to a control you must do it explicitly.

Another great thing with global resources is that it Visual Studio uses code generation to create a class in the Resources namespace with the same name as the global resource filename. Inside this class it adds properties for each resource key and value. So you use global resources in a strongly typed fashion. For example if I have a SharedResources.resx file in my App_GlobalResources folder. And inside this resource file I have a resource named ButtonSave, I can use the following code to access it.

image

Another way of accessing the same resource programmatically is by using the GetGlobalResourceObject method.

image

Where you need to pass the class name (resource file name) as the first parameter and the resource name as the second parameter.

When attaching a global resource to a control you need to use explicit attach. And also specify in the class name.

image

Using ASP.NET Server-Side State Management

Except from storing states on the client, you can also store state data on the server. It is a good practice to store very sensitive information, like bank information, on the server instead of the client. You might also have states that are application wide and not client specific that you need to store on the server.

In ASP.NET there is two ways of storing state on the server. There is application state and session state.

Application State

Application state information is is global to the application and is available to all pages, regardless of the identity of the client. It is a form of application-level caching of data that can be used for every request. Application data is stored in an instance of the HttpApplicationState class that is provided through the Page.Application property. This class is a key-value dictionary, where each value is stored and accessed by its key. You can add and read from the application state from any page on the server.

Data stored in the Application object is not permanent; it will be lost any time the application is restarted. In particular, IIS might restart you ASP.NET application at any point. To read an write values to the Application object you can do the following.

image

Because the Application object is not thread-safe, you need to lock it when writing data to it. In the example above it is not that important but imagine if you have a visitors counter that adds and remove visitor count. Then if it is not Locked/Unlocked you might end up with a incorrect number of visitors.

Application Events

Application events can be used to handle events raised by the Application, the most common events are Application_Start, Application_End and Application_Error.

  • Application_Start This event is raised every time the application is started.
  • Application_End This event is raised every time the application ends.
  • Application_Error This event is raised when there is an unhandled error propagating up to the application-level.

Session State

Session state is a user-specific state that is stored by the server. It is available only to pages accessed by a single user during a visit to you site. It is very similar to use as the Application state, but it the data is unique to the user. Session state is lost if the user ends hos or her session (or time out).

Reading and Writing Session Data

You read and write data the Session object the same way you would to for the Application object. The Session object is a an instance of the HttpSessionState class and represents a key-value dictionary collection. The following examples shows how.

image

Unlike the application there is no need to lock the Session object because it is user-specific and the value is only changed for the current user making the request.

ASP.NET writes a cookie to the client to keep track of the session. This cookie is called ASP.NET_SessionId and contains a random 24-byte value. Requests made by the client submits this cookie to the server and ASP.NET maps the cookie’s value to the session on the server. However if the client browser do not support cookies, or have it turned off, ASP.NET allows you to enable cookieless session state.

Without cookies ASP.NET tracks sessions by using the URL, embedding the session ID in the URL after the application name and before any remaining file or virtual directory identifier. For example.

image

This behavior can be configured by using the SessionState element in the web.config.

image

You can also disable session state entirely by setting mode=”off” in the SessionState configuration.

image

If you want to disable session state for a specific page you can use the EnableSessionState in the @ page directive on the page.

Session Events

The Session object have two events that can be handled by the developer. This two are Session_Start and Session_End. Like Application events they you handle them by creating methods in the Global.asax file.

  • Session_Start Raised when a new user requests a page on you site and thus begins a new session.
  • Session_End Raised when a session is abandoned or expires. This event can be used to log information or free per-session resources. This event is only raised when using the InProc session mode, more on that later.

The following shows an example of using the Session events.

image

Storing Session State

ASP.NET provides five ways of storing the session state on the server-side.

  • InProc Stores session states in memory on the web server. This is the default mode. It offers much better performans then the other two but is limited to only using one server. So you can not use this in a web farm.
  • StateServer Stores session in a service called the ASP.NET State Service. This ensures that session state is preserved if the web application is restarted and also makes session state available to multiple servers in a web farm. When configuring Session state mode to StateServer, remember to always set the ASP.NET State Service to startup type Automatic.
    image
  • SQLServer Stores session state in a SQL Server database. This ensures that session state is preserved if the web application is restarted and also makes session state available to multiple servers in a web farm. You will want to performance-test when using SQLServer mode.
  • Custom Enables you to specify a custom session stage storage provider. You also need to implement the custom storage provider.
  • Off Disables session state.

Configuring Session State Modes

You can configure the Session state mode in the sessionState element in your application’s web.config file. The following example shows the session state stored in a SQL server.

image

To use the SQLServer mode you need to create the ASPState database on the SQL server. To do this run the following command.

aspnet_regsql.exe -ssadd -sstype p -E
image

Then you have a new database in you SQL server.

image

Now the sessions state will be stored in the dbo.ASPStateTempSessions table.

image

Using ASP.NET Client-Side State Management to store information on the client

Almost every web application today need to store some information about a user to use later, for example a authentication token, theme name, or language. One thing to remember is not to store sensitive information on the client, like credit card numbers or bank information, even thou you can enable encryption on view state it is not as secure as storing that type of information on the server.

ASP.NET provides five ways of storing user information on the client.  The five ways are:

  • View state
  • Control state
  • Hidden fields
  • Cookies
  • Query string

View State

View state is a mechanism used in ASP.NET to store user-specific request and response data between page requests. The information in the view state is sent back to the user with the response of the page. When the user makes the next request the view state is returned with the request.

When the page is processed it pulls the view state data from the request and use it reset properties on the page and controls. View state is always enabled as a part on every ASP.NET page. The Page.ViewState property provides a dictionary object for retaining values between multiple requests for the same page. This object is of the type StateBag.
When a page is requested by the user the current state of the page and it’s controls is hashed into a string and saved in the page as an HTML hidden field called __VIEWSTATE. If data is to long for a single field (based on the value of the Page.MaxPageStateFieldLength property), ASP.NET performs a view state chunking to split it across multiple hidden fields. In the HTML response the view state hidden field looks like this.

image

As you can se the value in __VIEWSTATE is hashed, compressed and encoded for Unicode implimentations, this is to be a bit more secure and provide better performance.

When using view state you need to consider the security in using it. As said in the previous sentence, the view state is hashed, it also includes a message authentication code (MAC). This MAC is used by ASP.NET to determine if the view state data sent by the client have been tampered with. Do not mistake this as fully encrypted data, it is not. But for the most part it helps ensure security in many situations.
If you do store sensitive data in the view state, you would want to enable encryption on the view state. To do so you use the Page.ViewStateEncryptionMode property. This will secure the view state but also have a big impact on performance on the server, both CPU for encryption/decryption and bandwidth for the server and client because the view state sent between the two is much bigger.

To enable view state on the entire site you can set the following in the web.config.

image

If you want to set encryption on single pages you can do this in the @ page directive on each page.

image

Disabling View State Date 
View state is enabled by default for all the controls in your pages. This includes controls such as Literal and Label, that you might never need to include as part of the view state. It is a best practice to have view state enabled on as few controls as possible, this is because it minimize the amount of data sent back and forth between the client and server.

You can control the view state on the page level by enabling and disabling Page.EnableViewState and Page.ViewStateMode, for controls you can use Control.EnableViewState and Control.ViewStateMode.

The ViewStateMode is new in .NET Framework 4. The ViewStateMode property of a page or control has an effect only if EnableViewState is true. By default Page.EnableViewState is Enabled and Control.ViewStateMode is Inherited, which causes the control to use the page’s view state. There for if you do not change ViewStateMode, EnableViewState controls it entirely.

If you set EnableViewState to false, view state is disabled for the page or control, regardles of the value of ViewStateMode. If EnableViewState is set to true, you can set ViewStateMode to disable view state. Because ViewStateMode can inherit the page’s setting, you should always leave EnableViewState set to true and use ViewStateMode to control view state.

To disable view state for all controls on a page, simply set Page.ViewStateMode to Disabled. You can then selectively re-enable view state for specific controls by setting each control’s ViewStateMode property to Enable. Essentially, ViewStateMode allows you to opt in to view state, whereas EnableViewState requires you to opt out.

You can also disable view state for the entire website by setting enableViewState in the web.config file.

image

Custom View State
You can use the this.ViewState dictionary collection to read and write your own view state data. Adding data to the view state in this way is a efficient and secure way of storing data between requests. The view state is only stored for the same page, so this method of storing user data is only usable for storing temporary data for a single page. Below is a example of reading and writing your own view state data.

image

The result of the example looks like this;

image

and after the Submit button was clicked;

image

 

Hidden Fields

Hidden fields in HTML are simply input fields that are embedded in the page’s HTML, not displayed for the user. ASP.NET provides a control that lets you create your own custom hidden fields in a manner similar to how you create other controls. The HiddenField control allows you to store a store data in its Value property. You can add a HiddenField control to you page by using the following code in you markup.

image

To programmatically set the Value property of the HiddenField1 you do the following.

image

When viewing the HTML source of the page this is what you see.

image

What differentiate hidden fields from view state is that it is not encrypted, hashed or chunked and the user can view and modify the value.

 

Cookies

A cookie is a small amount of data that you write to the client to be stored and then passed with requests to your site. You write persistent cookies to a text file on the client machine. These cookies are meant to survive even if the user shuts down the browser and reopens it at a later time. You can also write temporary cookies that survive as long as the browser not shuts down because they are stored in the browsers memory. These cookies are used only during the current web session.

The mechanism that client and server use to create cookies is as follows.

  1. The client requests a page.
  2. The server responds with the HTML and a cookie
  3. The client request another page, and also sends the cookie in the request.

Cookies are a simple and reliable way of storing data on the client. However the client can delete a cookie at any time. No matter what expiration date the server have set.

Reading and Writing Cookies
A web application creates a cookie by sending it to the client as a header in an HTTP response. The following example shows how to read and write a cookie.

image

This checks to see if the cookie object exists in the Page.Request.Cookeis collection, if it exists, it writes the value otherwise it writes First time visitor. Then it sets the value of the lastVisit cookie, and set the Expires property to the next day.
If you do not set the Expires property the cookie is stored in the client’s browser memory and is removed when the browser shuts down. You can also create a cookie by using the Page.Response.Cookies.Add() method, which takes a HttpCookie object as a argument.

image

By default a browser do not send a cookie for a host to a website with a different host, this is a security feature. You also have control over the scope of the cookies. You can limit it to a specific directory on you web server or expand the scope to the entire domain. The scope of the cookie determines which pages have access to the cookie. To limit the scope of a cookie to a directory you specify the Path property of the HttpCookie class. For example,

image

This will limit the cookie so that it is only sent with the request in pages in the /MyApplication directory on the server.

To expand the scope of a cookie to the entire domain you specify the Domain property of the HttpCookie class.

image

Setting the Domain property will cause the cookie to be sent to all pages of the domain. It will also be sent with request to pages hosted on any subdomain of the domain specify. In the previous example that would mean the cookie would also be sent to www.frejnorling.com, private.frejnorling.com and so on.

Storing Multiple Values in a Single Cookie
The size of your cookie is dependent on the browser. Each cookie can be up to 4 KB in length. In addition, you can typically store up to 20 cookies per site. If you need to work around the 20-cookie limit, ASP.NET let you store multiple values in a single cookie by setting the cookie’s name and its key value. The following shows a example.

image

As you can se the property Expires is set just once for all values, this is because all values are stored in a single cookie on the client. When the client requests a page the server sends the following Set-Cookie header in the response back.

image

This will then be sent with every request made from the client, and the server will parse the string and populate the HttpCookieCollection accordingly.

You can not delete a cookie from the client, but you can change its Expires property to null. That will make the browser delete the cookie from the client when the browser shuts down.

 

Query Strings

So query strings, there is not that much to say about them that have not been said before. But you give you a short summery of them anyway.

Query strings are set off from the URL with a question mark (?) followed by the query string term, or parameter name, an equal sign (=) and the value. You can append multiple query string parameters by using the ampersand (&). A typical query string might look like this

http://www.frejnorling.com?lang=en&theme=blue&q=hello+world

Values sent to your page via query string can be retrived on the server through the Page.Request.QueryString property.
To access the lang parameter in the example URL above you write the following.

Request.QueryString[“lang”];

There is a browser length limitation on query string, the maximum length of a query string is 2083 characters long. But if you want to send a URL link in a mail, you would use a maximum of 70 characters for the URL.

To add a query string value to your site, you need to manually append it to the hyperlink.

The ASP.NET Application Life Cycle, Page Life Cycle and Control Life Cycle

On a ASP.NET application running on IIS 7.5 the life cycle of your application looks like the following list.

  1. A user first makes a request for a page in you site.
  2. The request is routed to the processing pipeline, which forwards it to the ASP.NET runtime.
  3. The ASP.NET runtime creates an instance of the ApplicationManager class. The ApplicationManager instance represents the Microsoft .NET Framework domain that will be used to execute requests for you application. An application domain isolates global variables from other applications and allows each applications to load and unload separately as required.
  4. After the application domain has been created, an instance of the HostingEncironment class Is created. This class provides access to items inside the hosting environment, such as directory folders.
  5. ASP.NET creates instances of the core objects that will be used to process the request. This includes HttpContext, HttpRequest and HttpResponse objects.
  6. ASP.NET creates an instance of the HttpApplication class (or an instance is reused). This class is also the base class for a site’s Global.asax file. You can use this class to trap events that happen when your application starts or stops. When ASP.NET creates an instance of HttpApplication, it also creates the modules configured for the application, such as the SessionStateModule.
  7. Finally, ASP.NET processes requests through the HttpApplication pipeline. This pipeline also includes a set of events for validating requests, mapping URLs, accessing the cache, and more. These events are of interests to developers who want to extend the Application class.

Responding to Application Events

As said in the last item in the previous list, the HttpApplication class provides a several events you can handle to perform actions when ASP.NET raises certain events on the application level, the events wont work on a per-user level.

The following is some the most common events used by developers.

  • Application_Start  The Start event is raised when you application is started by IIS (usually as the result of a user request). This event is useful for initializing variables that are scoped at the application level.
  • Application_End  The End event is raised when your application stops or shuts down. This event is useful if you need to free application-level resources or perform some sort of logging.
  • Application_Error  The Error event is raised when an unhandled error occurs and rises up to the application scope. You should use this event to perform worst-case, catch-all error logging.
  • Application_LogRequest  The LogRequest event is raised when a request has been made to the application. You can use this event to write custom information regarding a request.
  • Application_PostLogRequest  The PostLogRequest event is raised after the logging of a request has completed.

Other events include Application_BeginRequest, Application_EndRequest, ResolveRequestCahce, and many others.

You can respond to these events by adding event handling methods in your Global.asax file.

image

The previous code tracks the number of requests made to the website, and store it in the global Application object.

The Page Life Cycle

Besides from the Applications life cycle there is also the Page life cycle for each page in a website. The following is a list of the page life cycle.

  1. The user makes a request to for a page.
  2. On the webserver, the ASP.NET compile the page (if necessary), or pull from cache (if available).
  3. (Start) Set request and response objects. Determine IsPostBack.
  4. (Init) Initialize page controls (but not their properties). Apply page theme.
  5. (Load) If PostBack, load control properties from view state.
  6. (Validation) Validate page and validator controls
  7. Call control event handlers (for PostBack request).
  8. (Rendering) Save view state. Render controls and display the page.
  9. (Unload) Unload request and response objects. Perform cleanup. Page is ready to be discarded. Return response to user.

Responding to Page Events

As with the Application events, the page raises various events through its stages. This events can be handled by the developer. It is important to know the order in which events are called, so that your code runs in the proper sequence. The following table shows a order list of the most common events of a page.

Event Descrition
PreInt This is the first real event you might handle for a page. You usually use this event only if you need to set values such as master page or theme.
This event is also useful when you are working with dynamically created controls for a page without a master page. You should create controls inside this event. If you have a master page or theme, create controls in the Init event.
Init This event fires after each control has been initialized. You can use this event to change initialization values for controls.
If you need dynamically added controls to a content page, use this event.
InitComplete This event is raised after all initializations of a page and its controls have been completed.
PreLoad This event fires before view state has been loaded for the page and its controls and before postback processing. This event is useful when you need to write code after the page is initialized but before the control view state has been re-established.
Load The page is table at this time; it has been initialized and its state has been reconstructed. Code inside the page load event usually checks for postback and then sets control properties appropriately.
The page’s load event is called first. Then the load event for each child control is called in turn (and then the load events for their child controls, if any).
Control (postback) events ASP.NET now calls any events on the page or its controls that caused the postback to occur. This might be a button’s click event, or a drop down list’s SelectedIndexChanged event.
LoadComplete At this point all controls are loaded. If you need to do additional processing at this time, you can do so here.
PreRender This event allows final changes to the page or its control. It takes place after all regular postback events have taken place. This event takes place before ViewState is saved, so any changes made here are saved.
SaveStateComplete Prior to this event, the view state for the page and its controls is set. Any changes to the page’s controls at this point or beyond are ignored. This event is useful if you need to write processing that requires the view state to be set.
Render This is a method of the page object and its controls (not an event). At this point, ASP.NET calls this method on each of the page’s controls to get its output.
The Render method generates the client-side HTML, Dynamic Hypertext Markup Language (DHTML), and scripts that are necessary to properly display a control on the browser.
This method is useful if you are writing your own custom control. You override this method to control output for the control.
Unload This event is used for cleanup code. You can use it to manually release resources, a process that is rarely necessary.

 

Dynamically add controls to a page

To dynamically add controls to a page you do this in the Page.PreInit event (when not using themes or master pages) or in Page.Init when using themes or master pages. The following example adds a textbox and a button and also handle the button Click event.

image

And the result looks like this.

image

After submit!

image

Control Life Cycles Events

Controls such as Button and Textbox share a common life cycle with the Page class. Each server control, including Init, Load, Render, and Unload, goes through the same life cycle as a page.
A control’s event is raised during the same event for its parent, so when a page executes the load event, all controls load event is also executed. And their child control executes the load event and so on.

Controls in ASP.NET have default events that are usually handled by the developer. For example, the Page object’s default event is Load, and the Button object’s default event is the Click event.

To handle a Page or Control event all you need to do is crate a Event Handle Method in the code behind file (C#). To do this you write a new method and set the method signature to comply to the event signature of the event. Like the following method to handle the Unload event for a button.

image

To programmatically add this event handler to the button you add a new EventHandler object to the Unload property of the button.

image

You can also set the event handler in the ASP.NET markup code like the following example.

image

 

Controlling the Automatic Postback

A control like the Button always cause a postback to the server when clicked, but a control like DropDownList do not cause a postback when a user select a choise.

To make a control do a postback on certain events you need to add the AutoPostBack=”true”

image

Now you need to add a event handler for the SelectedIndexChange event caused by the drop down list.

image

Then add a event handler to the SelecteIndexChanged property for the drop down list.

image

Now you can automatically handle selections on the drop down list in a method.

How to use ASP.NET Themes

If you have read my previous post on master pages to handle different styles of a webpage you might thing that was not a good way of handling different styles for different users or devices, and guess what, you are right. There is a “better” way, or another way of doing the same thing, say hello to Themes.

What is Themes?

A theme is a way of controlling the look and feel of a webpage. You can have many themes on you website and apply them for different users or devices. A theme in ASP.NET can control what Cascading Style Sheet (CSS) is added in the <head> tag, what styling properties each controls get and what images to be showed for each theme.

Ok I get it, show me how!

Implementing themes is very easy. All themes is located in the special ASP.NET folder App_Themes. And each theme is placed in a sub-folder of the App_Themes folder i.e. /App_Themes/Red, /App_Themes/Blue for a red and blue theme.

It will look like the following,

image

In those folders (Red and Blue) you can add .skin files (a skin file is a text file with the markup for a ASP.NET control that will be used as a template for controls in the ASP.NET)

image

It is common to create a .skin file for each control you want to “theme”.

image

This two textbox controls are just templates of what the textbox controls will look like in the ASPX pages.
Notice the second line, there is a property skinid when applying a skinid property in the template .skin file, only controls with the same skinid will get the theme from that template.

The ASPX file have this two controls.

image

The result of this template looks like this.

image

The first textbox get the looks from the first line in the .skin file while the second have the SkinID property set to blueTextbox and therefor get the properties form the second line in the .skin file.

One thing to keep in mind is that the first line in the .skin file will apply to ALL textboxes that on all pages that implement the template.

What about style?

Implementing different style sheets for each theme is even easier. All you have to do is add a .css file in the theme folder, name it to whatever you want and when that theme is selected for a page it will automatically add a link to that css file in the <head> tag.

image

<head>
<title></title>
<link href="Styles/Site.css" rel="stylesheet" type="text/css" />
<link href="App_Themes/Blue/blue.css" type="text/css" rel="stylesheet" />
<link href="App_Themes/Blue/style.css" type="text/css" rel="stylesheet" />
</head>

The Site.css is added in the master page in this case, and both blue.css and style.css is added from the theme folder. Very easy to do.

You said different images to?

Yes I did, when you want to specify different images to use for different themes, you do it the same way you do for controls.
Create a new .skin file in App_Themes/Blue folder, name it logo.skin or something else, type the following code in it.

image

This will set the ImageUrl property on all Images controls using skinID=”logo” to “~/App_Themes/Blue/logo_blue.jpg”.

To the same for the Red theme.
image

Now you just add a Image control to the page or master page, set the skinid to “logo” and your logo will change depending on the active theme.

image

 

Well how do I set the theme on the page then?

You can either set the theme for all pages in the web.config file or in the @ Page directive on each file.

To set a theme in the web.config file just add the following tag in the <pages theme="Red"></pages> in the <system.web> tag.

To set the theme on the page level add Theme="Blue" in the @ Page directive.

Themes have a priority among themselves for overriding each other, the priority goes as follows (first to last):

  1. Theme attributes in the @ Page directive
  2. <pages Theme=”themeName”> elements in <system.web> section of a Web.config file.
  3. Local control attributes
  4. StyleSheetTheme attributes in the @ Page directive
  5. <pages StyleSheetTheme =”themeName”> elements in <system.web> section of a Web.config file.

The difference between using Theme and StyleSheetTheme is that StyleSheetTheme can be overriden by local control attributes, this is true for both @ Page directive and when the theme is specified in the pages element in Web.config.

Apply a theme programmatically, just set the Page.Theme or Page.StyleSheetTheme to the theme name.

image

image

Now you are all set to implement themes in your website.

Follow

Get every new post delivered to your Inbox.