Register | Login 
View Article  

Current Articles | Categories | Search | Syndication

Developing a custom ASP.Net 2.0 server control

By Chad Bryant on Sunday, December 03, 2006 :: 2737 Views :: 0 Comments :: C#, ASP.NET

The purpose of this article is to demonstrate how to create a simple composite server control for ASP.Net 2.0.  Just as important, or more importantly, it demonstrates the benefits of creating your own custom server controls.  I will demonstrate these points by walking through a simple example scenario where the task is accomplished without the use of a custom control.  We will then turn the solution into a custom server control that can be reused throughout our sites and across various other projects where such functionality would be useful.

The control we will develop will extend the capabilities of the Button control provided with ASP.Net.  I have had a couple of instances where I found myself using a Button control and then adding a label above it to display a message when the button was clicked by the user to give some type of user feedback while the post back process was occurring.   To prevent the user from clicking submit more than once (i.e. during a credit card processing scenario), you may want to disable the button as well.  This is a great candidate for a custom server control because of the opportunity to reduce redundant code on every page where you employ such functionality and to simplify the development of pages that use this functionality by not having to write the same code over and over again.  In addition, wrapping this functionality into a custom control makes it easier to provide a consistent user experience.

To begin, let’s take a look at the end result.  I always like to begin with the end in mind as it puts everything in perspective and gives us direction on where we’re headed.  Figure 1 shows the button on a page before the user has clicked submit. Figure 2 shows us what they see after clicking the submit button while waiting for the server side post back to complete. 

chad1.gif

Figure 2.  Example of disabling the submit button and giving user feedback during the post back operation while the credit card is being processed server side.

Let’s look at code we might put on each page to accomplish this functionality.  First, let’s assume we have put a Label control on the page and given it an ID of lblProcessingMessage and we’ve set its text property to an empty string.  The following page load code in Figure 4 will setup the client side JavaScript for the onClick event of the submit button. 

chad2.gifFigure 3.  The page load code to setup the client side onClick code for our submit button.

This is accomplished by adding an attribute to btnSubmitOld (our submit button representing the old redundant way of accomplishing this task).  What we’re adding is an onClick handler for the button for the client side JavaScript.  Notice that we are disabling the button and changing the inner text of the label (rendered as a span tag in the browser) to display our processing message.  In addition to this, notice that we need to tap into the JavaScript that posts the form back to the server when the button is click to perform the post back.  If we leave this piece off, we’ll have a processing message and disabled button only and no post back will occur since we have overridden the normal automatic post back handling that would have occurred for our button.  This is easy to do by simply using the GetPostBackEventReference method of the ClientScript property (this is a property of the Page object in 2.0, in 1.x the GetPostBackEventReference method was a method on the Page itself, but this has been made obsolete with 2.0).

Just to solidify the above explanation Figure 4 shows the rendered html source for our button.  Notice the onClick code that is added as an attribute to our input submit button tag. 

chad3.gif

Figure 4.  The rendered html code for our submit button.

The above code works well to accomplish our requirement of disabling the submit button on click and displaying a processing message to the user during the post back event.  However, it is likely that we may want to employ this technique on various pages throughout our site.  Maybe we want to consistently disable button clicks and provide some sort of message to the user during the post back.  We could wrap this into a user control that could be reused throughout the site on various pages which would accomplish our goal of reducing redundant code and providing a consistent user experience.  This would also achieve the goal of having this code maintained in one location for ease of maintenance.  However, we may want to use this control in other applications and other web sites and since user controls are not compiled into an assembly, it makes reuse across applications more difficult and we would end up copying source code and again face the issue of redundant code.  Clearly, a better solution would be to make this a custom server control that we could build into an assembly and use over and over again in various projects.  Our assembly could be copied to the bin folder and deployed using xcopy deployment or it could be setup to be installed in the GAC.

Now that the goal is clear, let’s take a look at how to turn this into a custom server control.  We will derive our control from CompositeControl.  CompositeControl is new in 2.0 and provides a couple of features that deriving directly from Control in 1.x did not.  The first thing it does is it implements the INamingContainer interface for us.  This interface simply makes sure that our controls have a unique ID by concatenating a reference to the parent control down to the child control.  By deriving from CompositeControl, you no longer have to implement this interface explicitly.  The second thing CompositeControl does for us is it provides an associated control designer that ensures that child controls are displayed on the design surface. We will go through the code from top to bottom walking through the code one piece at a time.

The following code creates our custom control class and derives from CompositeControl as already noted.  Also worth noting are the attributes used for our ProcessButton control.

chad4.gif

The first two attributes setup the permissions which are required to ensure that code that links to the control has the appropriate security permissions.  The next two attributes define the default event and default property selected in the property browser when the control is selected on the design surface.  The final attribute is used to setup the source view format string.

The next snippet of code illustrates setting up the private fields and public properties that we’ll expose to page developers using on the control.

chad5.gif

Notice in the above code our property ButtonText.  We want to allow the page developer to set the text for our contained button and we expose it via the ButtonText property in our control.  Notice the attributes we have set for our property.  Use the Bindable attribute to control whether the property supports data binding.  The category attribute sets the category in the property browser where the property will appear.  DefaultValue sets the default value for the property and the description provides a text description for the page developer which appears in the bottom area of the property browser.  The other point to note is the call to EnsureChildControls.  This ensures child controls get created which in our case is our child Button control.

The next code snippet outlines the methods we need to setup to handle the child button’s button click event and then raise the event and provide the event handler for page developers to use to handle the click event of our control.

chad6.gif

 

Finally, the last three methods provide the remaining pieces of code to make our control complete.  In CreateChildControls we setup our child Button control and add it to the Controls collection to be rendered.  Finally we override the Render method where we will check our properties to see if we need to do the special rendering which handles the client side JavaScript we want our custom control to provide to handle potentially disabling the submit button on click and displaying a status message to the user on click.  And finally we let our submit button render itself.  One thing I would like to point out is that we are making use of a new property for the ASP.Net 2.0 Button control. The OnClientClick property allows a button to easily respond to client side and server side click events without the extra code needed to add the onclick client side code to the attributes of the Button as we did in 1.1.

chad7.gif

To test your server control, it is easiest to add a class to the App_Code folder in your web site solution in Visual Studio 2005 and put your control code there temporarily.  This way you can test and continually make changes to the code as you work with the control before you finally build it into a reusable assembly.

This article has demonstrated how easy it is to create a simple composite server control in ASP.Net.   By creating custom controls we can provide reusable objects that can be used throughout our projects and even in other projects.  This reduces redundant code and makes it easier to provide a consistent user experience.   This article has only touched on the basics of custom server control development and other topics such as designers, smart tags, and creating templated controls have not been addressed.  Asp.Net 2.0 provides a number of enhancements for addressing these needs and there is an abundance of resources on the web and in various books that go into greater detail providing guidance on advanced topics in custom control creation for ASP.Net.

Use the link below to download the source code for this article.  The attached zip file contains a Visual Studio 2005 web site that implements techniques outlined in this article.  Note that the code for the custom server control is contained in the App_Code folder in the ProcessButtonTest.cs file.  Once the control has been tested and debugged, it can be compiled into a DLL to be reused in other projects.  Have fun!

Download the code

 




Chad Bryant is a senior developer with The Delta Group, a Greenville, SC based firm providing web based software to the healthcare industry. In addition to programming, Chad enjoys running marathons, spending time with his wife and three daughters, and reading books. Chad can be contacted via email at chadbryant5@charter.net

Previous Page | Next Page

COMMENTS

Currently, there are no comments. Be the first to post one!
Click here to post a comment

Copyright (c) 2008 GSP Developers
Walling Info Systems | Terms Of Use | Privacy Statement