When you add script manager control on the page, it not only goes though page life cycle on the server but the request goes through series of events on the client side. There are two client side objects available in asp.net Ajax; Sys.Application and Sys.WebForms.PageRequestManager object. Sys.Application events are raised because of scriptmanager and PageRequestManager events gets raised only when there are updatePanels present on the page. In order to illustrate all these events I will use tracing feature available in asp.net Ajax. By using Sys.Debug.trace, I will write trace messages to a textarea with id equal to TraceConsole. If you have Firebug extension installed on firebox, the traces get automatically written to the trace console of Firebug. Here is how my markup looks like.

In the above code, I am making use of application page load event which gets automatically called by asp.net Ajax framework if you name it exactly as pageLoad. In the application pageLoad event I am register most of the events that gets raised by PageRequest Manager. Probably in future blog postings I will cover in details about what these events do and how you can leverage them in the client side framework. I also have a text area which is where all the traces gets written to. It is essential that you use id of TraceConsole for the output of Debug trace to get written to the textarea. When the page gets posted by the button inside of UpdatePanel, I am writing out the event name that gets raised in the trace console. Here is an example of the output that gets written.
Here is the resulting output being written to the firebug trace console when viewing the page in FireFox.

I am sure many of you have been in a situation where you have a form view or details view control inside of an UpdatePanel and after inserting a successful record into the database you went to send a small JavaScript to the end user saying that your record got successfully inserted into the database. I made use of ItemInserted event of FormsView control and used the Page.ClientScript.RegisterStartupScript to inject the JavaScript into the output stream. Unfortunately this ClientScript on the page object does not work when you are inside of an UpdatePanel. Here is the markup and codebehind of my page.

The code behind is as follows
The markup is the usual stuff that we do in .net 2.0 so I wont be covering that. In the code behind I am making use of Page.ClientScript.RegisterStartupScript to register my script. However this does not work. Instead you have to make use of the method exposed by ScriptManager to send the JavaScript to the browser. Here is how the new code looks like.

Today when I was working with creation of server controls, I realized that I wanted my server controls to work out of the box using default values when you drag and drop the control onto the designer surface. That's when I started digging into what do I needed to do on my server controls to set default values. Sure enough I welcomed the new attribute ToolBoxData in which you can specify default values for the properties of your control when it gets dragged. Here is an example of Address server control in which I am setting default values for the properties address,city, state and zip on my address control.

In the above example I am making use of ToolBoxData attribute at the class level and setting default values for the properties of my control. Once I set these properties and drag the control this is what visual studio puts on the designer.

Continuing with my exploration in server controls, i discovered a small nuisance when i you drag your custom controls from the toolbox onto the designer. For some reason visual studio would automatically prefix the server control with cc1 tagprefix as shown in the example below.


If you don't like the default cc1 tag prefix, you can declare the following prefix in the assmeblyInfo.cs file and when you drag the control next it will use the tag prefix specified in the custom control. Here is an example of assemblyInfo.cs


As you can see from the screen shot above after specifying the default tag prefix when i drag the address control visual studio automatically uses custom tag prefix.
Continuing with my discovery of server controls, I have come across few more goodies. As I mentioned in my earlier blog posting that there are two different ways of writing content when you override RenderContents method inside of a server control. Here is an example of two different approaches.


In the above screen shots, I am showing 2 different approaches. In the first approach, I am using the built in enumerations where as in the second approach I am manually typing in the html. Writing html using the first approach has lot of benefits. First it gives you strongly typed access to the html content. Secondly asp.net framework supports two kinds of rendering; Html 4.0 and html 3.2 standard. If you write your html using the predefined enumerations as shown in the first approach, you get of out of the box adaptive rendering behavior based on configure settings to spit out either html 4.0 html or html 3.2 html. There are various ways and configuration that help asp.net runtime determine what kind of html standard to send to the user's browser.
HtmlTextWriter are objects available in asp.net that is responsible for generation the html output that gets sent to the browser. There are two kinds of HtmlTextWriter available. One is HtmlTextWriter and second one is called Html32TextWriter. When a request is received by the asp.net runtime, it inspects the tagwriter property inside the user agent string and determines what textwriter to use to render html content. You can configure this setting by changing the values defined inside browsercaps element inside of machine.config for each of the different browsers available in the market.
If you have a custom server control that you are going to use in several different pages. It might be worth while to register the server control in web.config file instead of registering it in several different pages. Here is an example of registering my custom controls library in web.config file.

once you have registered the server control, you can declare this server in any aspx or ascx page as follows

This topic may not sound too interesting too people because it is an old story. Basically in order to store anything in gac you have to strongly name an assembly. I don't happen to put assemblies in GAC too often so I simply forget the process of strongly naming an assembly. This time around I decided to write a blog post so that I would always have something to look back into.
Say you have a class called CustomTextBox.cs in a project called ServerControls. In order to strongly name the assembly you will add another class called AssemblyInfo.cs. Strongly named assembly consists of 4 parts; assembly name,version, culture and public key token. You will define assembly culture,version and assembly key file inside AssemblyInfo.cs. Assembly key file contains the location of file with the signature to sing the assembly. Here is how it might look like.

In order to generate the assmeblyKeyFile you will have to go to the visual studio command prompt and run the following command.
sn -k mykey.snk
This will generate mykey.snk file that has the signature to sing the assembly. Make sure the key file exists in the same location as the assemblyinfo.cs
If you are not using visual studio you would use the following command in the command prompt to strongly name the assembly.
csc /t:library /out:CustomControls.dll AssmeblyInfo.cs CustomTextBox.cs
Once again in my adventure of writing custom controls I have discovered that if you are overwriting custom CreateChildControls to add your own controls to the control collection, you should initialize the controls before adding them to the control collection. Here is an example where I am setting properties on the link button after I add them to the controls collection.

The reason this is not a good approach is because of the magic that happens when you call controls.Add. This is a phase when .net framework calls an internal method called StartTrackingViewState. Basically once the control is added to the control collection, it gets tracked. Anything that you do to the control after adding it to the control collection gets recorded in the viewstate causing the page size to increase. Since childcontrols gets called every time the control needs to get initialized, the initialization code for the control will execute every time and therefore there is no need to have anything being persisted to the viewstate. So as good practice always initialize your controls before adding them to the controls collection as follows.

At my current work, I had my share of custom controls that I have to write. Basically I started to write my html by overriding the render contents. I had been using the old style RenderBeginTag and than add my styling by calling write attribute. It is nice but the problem that I have with is at the end I have to know which tag to close which is sometimes a pain. Therefore when I found this new method called RenderBeginTag, I thought it was nice because when I have to close the tag I simply have to say RenderEndTag and it automatically figures out the tag I have to close. Here is a simple code showing two different ways of doing it.

Once I change it to the new RenderBeginTag, life is much simpler. Here is how the code would look like.

Today at work, one of my co-workers mentioned an issue that he was loosing ConnectionString every time he would modify the linq to SQL model in the dbml file. What he was essentially doing was getting rid of the default constructor and adding a partial class where in the default constructor based on business rules, he would fetch the right ConnectionString either from web.config, app.config or some other xml file. Obviously the problem here was, you cant have two default constructors. Because every time you would modify the dmbl file any changes you have made to the designer.cs would get lost. But a simpler solution to this would simply be creating your own partial DataContext class and adding the OnCreated partial method which gets called in the default constructor. Here is a simply implementation where I am reading the ConnectionString from web.config ConnectionString section.

More Posts
Next page »