Friday, January 29, 2010

Wrapping up the "An introduction to ASP.NET Ajax 4" series

I'm wrapping up the "An introduction to ASP.NET Ajax" series today.

Although the posts were short and didn't go in depth, I hope I've been able to encourage you to dig some deeper yourself.

You can find all the posts here: You might also find this collection of ASP.NET Ajax 4.0 Beta Resources useful.

I'd highly appreciate it if you give me your opinion on these series. You can leave a comment or holler at me at Twitter.

An introduction to ASP.NET Ajax 4: The Minifier

The Minifier is an utility which "minifies" your scripts: it reduces the size of your scripts by removing comments, removing spaces, renaming local variables and removing unreachable code.

You can download the Minifier on Codeplex.

Before and after

The unminified script looks like this.

   1:  //This function does something
   2:  function doSomething(valueOne, valueTwo){
   3:      var result = valueOne + valueTwo;
   4:      return result;
   5:  }

After hypercrunching the script looks likes this.

   1:  function doSomething(a,b){var c=a+b;return c}

Thursday, January 28, 2010

An introduction to ASP.NET Ajax 4: Ajax Templating

ASP.NET Ajax 4 contains a powerful templating engine. The Dataview makes it very easy to bind JSON data to HTML elements.

You can bind the JSON data to the Dataview imperatively or declaratively (mapping html elements with javascript).

Some code examples shows best.

Example (Imperatively)

   1:  <html xmlns="http://www.w3.org/1999/xhtml">
   2:  <head runat="server">
   3:      <title>Demo - Ajax Templating</title>      
   4:      <script src="Scripts/Start.debug.js" type="text/javascript"></script>       
   5:      <!-- Script -->
   6:      <script type="text/javascript">
   7:          Sys.Debug = true;
   8:      
   9:          var events = [
  10:                 { Street: 'Laarsveld', City: 'Geel', Priority: 2 },
  11:                 { Street: 'Noorderlaan', City: 'Antwerpen', Priority: 1 },
  12:                 { Street: 'Meir', City: 'Antwerpen', Priority: 5 },
  13:                 { Street: 'Groenplaats', City: 'Antwerpen', Priority: 1 },
  14:                 { Street: 'Bredabaan', City: 'Antwerpen', Priority: 1 }               
  15:             ];       
  16:                   
  17:          Sys.require(Sys.components.dataView, function(){
  18:              Sys.onReady(function () {
  19:                  Sys.create.dataView("#eventList1", { data: events });                       
  20:              });
  21:           }
  22:          );                      
  23:         </script>  
  24:     </head>  
  25:     <body>  
  26:         <h1>Events</h1>  
  27:         <table>            
  28:              <thead>
  29:                  <tr><th>Street</th><th>City</th><th>Priority</th></tr>
  30:              </thead>
  31:              <tbody id="eventList1" class="sys-template">
  32:                  <tr align="center"><td>{{Street}}</td><td>{{City}}</td><td>{{Priority}}</td></tr>                           
  33:              </tbody>
  34:         </table>                           
  35:     </body>  
  36:  </html>


Example (Declaratively)

   1:  <html xmlns="http://www.w3.org/1999/xhtml">
   2:  <head runat="server">
   3:      <title>Demo - Ajax Templating</title>      
   4:      <script src="Scripts/Start.debug.js" type="text/javascript"></script>       
   5:      <!-- Script -->
   6:      <script type="text/javascript">
   7:          Sys.Debug = true;
   8:      
   9:          var events = [
  10:                 { Street: 'Laarsveld', City: 'Geel', Priority: 2 },
  11:                 { Street: 'Noorderlaan', City: 'Antwerpen', Priority: 1 },
  12:                 { Street: 'Meir', City: 'Antwerpen', Priority: 5 },
  13:                 { Street: 'Groenplaats', City: 'Antwerpen', Priority: 1 },
  14:                 { Street: 'Bredabaan', City: 'Antwerpen', Priority: 1 }
  15:             ];
  16:          Sys.require(Sys.components.dataView);         
  17:     </script>  
  18:     </head>  
  19:     <body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView">  
  20:         <h1>Events</h1>  
  21:         <table>            
  22:              <thead>
  23:                  <tr><th>Street</th><th>City</th><th>Priority</th></tr>
  24:              </thead>
  25:              <tbody id="eventList1" class="sys-template"
  26:                     sys:attach="dataview"
  27:                     dataview:data="{{events}}">
  28:                  <tr align="center"><td>{{Street}}</td><td>{{City}}</td><td>{{Priority}}</td></tr>                           
  29:              </tbody>
  30:         </table>                           
  31:     </body>  
  32:  </html>


Both ways have the same result.

Wednesday, January 27, 2010

An introduction to ASP.NET Ajax 4: Client Controls

Client Controls are controls from the Ajax Control Toolkit made available client-side.

This means you can now use these awesome controls without using ASP.NET WebForms.

You can instantiate these controls imperatively, declaratively or imperatively with jQuery. All controls are exposed as jQuery plugins automatically.

You can find these controls in the ExtendedControls script.

Example

This example shows you how to hook a color picker to an input element using jQuery and the ExtendedControls.


   1:  <html xmlns="http://www.w3.org/1999/xhtml" >  
   2:  <head>  
   3:      <title>Demo - Client Controls</title>  
   4:      <!--Styles-->   
   5:      <link rel="Stylesheet" type="text/css" href="http://ajax.microsoft.com/ajax/beta/0911/extended/colorpicker/colorpicker.css" />            
   6:      <!--Scripts-->

   7:      <script src="http://ajax.microsoft.com/ajax/beta/0911/Start.debug.js" type="text/javascript"></script>    
   8:      <script src="http://ajax.microsoft.com/ajax/beta/0911/extended/ExtendedControls.debug.js" type="text/javascript"></script>       
   9:      <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>          
  10:      <script type="text/javascript">
  11:          Sys.Debug = true;
  12:   
  13:          Sys.onReady(function(){        
  14:              Sys.require(Sys.components.colorPicker, function () {
  15:              $("#colorPicker").colorPicker({});
  16:              });            
  17:          });        
  18:      </script>  
  19:  </head>  
  20:  <body>  
  21:      <div>  
  22:          <form id="form1" action="/">
  23:          <div><input type="text" id="colorPicker" /></div>                                                 
  24:          </form>
  25:      </div>  
  26:  </body>  
  27:  </html>  



Tuesday, January 26, 2010

An introduction to ASP.NET Ajax 4: The Scriptloader

The Scriptloader tries to make the complexity of loading scripts easier.

Core features

The core features of the Scriptloader are:
  • Automatically resolving dependencies
  • Lazy loading
  • Parallel loading
Automatically resolving dependencies

You need the Start script to start using the Scriptloader. Use Sys.require to load the component(s) you need. The dependencies get resolved automatically. In this example I load the DataContext component.


   1:  <html>
   2:      <title>ScriptLoader Demo</title>    
   3:      <head>
   4:          <script src="http://ajax.microsoft.com/ajax/beta/0911/Start.debug.js" type="text/javascript"></script>
   5:          <script type="text/javascript">
   6:              //Enable debugging
   7:              Sys.Debug = true;
   8:              
   9:              //Resolve dependencies
  10:              Sys.require([Sys.scripts.DataContext]);                 
  11:          </script>
  12:      </head>
  13:      <body>
  14:      </body>
  15:  </html>


Using Internet Explorer developer tools you can see all the extra scripts are downloaded. The Scriptloader downloaded all the DataContext's dependencies automatically.



Lazy loading

In this example the scripts get downloaded in the background after clicking the button.

   1:  <html>
   2:      <title>ScriptLoader Demo</title>    
   3:      <head>
   4:          <script src="http://ajax.microsoft.com/ajax/beta/0911/Start.debug.js" type="text/javascript"></script>
   5:          <script type="text/javascript">
   6:              //Enable debugging
   7:              Sys.Debug = true;    
   8:                                  
   9:              //Lazy Loading
  10:              function doSomething(){
  11:                  Sys.require([Sys.scripts.DataContext]);
  12:              };
  13:              
  14:          </script>
  15:      </head>
  16:      <body> 
  17:          <input type="button" onclick="doSomething()" value="Do something"/>
  18:      </body>
  19:  </html>


Parallel loading

Using the script tag makes scripts load in serial. If you use the Scriptloader, the scripts get loaded in parallel, improving performance.

Apply this to your own scripts

The Scriptloader is also capable of loading other scripts. Find out how on the ASP.NET Ajax Wiki.

Monday, January 25, 2010

An introduction to ASP.NET Ajax 4: The CDN

Microsoft is providing a free content delivery network hosting ASP.NET Ajax and jQuery. Next to these scripts, they are also hosting some stylesheets which play together nicely with the Client Controls.

Define

Here is a definition I found on Wikipedia.
A content delivery network is a system of computers containing copies of data, placed at various points in a network so as to maximize bandwidth for access to the data from clients throughout the network. A client accesses a copy of the data near to the client, as opposed to all clients accessing the same central server so as to avoid bottleneck near that server.

Improving performance

Using the CDN will improve the performance of your webapplication in several ways:
  • The number of networkhops gets reduced.
  • Browsers can reuse cached JavaScript files for webapplications that are located in different domains.
  • The load on your own webserver gets smaller.

How to use

If you use the Scriptloader you only need to reference to one script on the CDN. It will automatically download the other scripts from the CDN.

   1:  <script type="text/javascript" src="http://ajax.microsoft.com/ajax/beta/0911/Start.debug.js"></script>  

Click here for the full CDN directory listing.

More facts and pretty graphs

As I mentioned in this post, this free e-book shows you how ASP.NET Ajax 4 can make your webapplications faster. There's a whole chapter on the CDN in there.

Sunday, January 24, 2010

Presenting the "An introduction to ASP.NET Ajax 4" series

I have been playing with the ASP.NET Ajax 4 beta library the last weeks. Now I grasp the basics, I wrote a short series showing the core features of this library.

I tried to keep the posts as small and easy-to-grasp as possible. Once you grasp the basics I encourage you to play with it yourself and take a look at more advanced concepts. In this post I made a list of useful resources.

Topics which will be covered in these series are:
  • The CDN
  • The ScriptLoader
  • Client Controls
  • AJAX Templating
  • The Minifier

Wednesday, January 20, 2010

Log4Net: log.Debug(String.Format()) versus log.DebugFormat()

Log4net is one of the most popular opensource logging frameworks available in the .NET world. I've been using this framework for over a year now, and today I discovered something new.

I often use string.Format() to format my log messages. Earlier this morning I made a typo formatting my message and an Exception was thrown in the beginning of my method which caused the application flow to break. You can avoid this by using the DebugFormat() method. If you mistype here, no Exception will be thrown, but a WARN message will be logged.

Example using log.Debug(String.Format())

   1:  try
   2:  {
   3:      if (log.IsDebugEnabled)
   4:      {
   5:          log.Debug("Starting to insert item ABC_1.");
   6:          //Insert item ABC_1
   7:          log.Debug(string.Format("Item {0} inserted with success. Started inserting item {1}.", "ABC_1"));
   8:          log.Debug("Starting to insert item ABC_2.");
   9:          //Insert item ABC_2
  10:          log.Debug(string.Format("Inserted item {0}.", "ABC_2"));
  11:      }
  12:  }
  13:  catch (Exception ex)
  14:  {
  15:      log.Error("Woops", ex);
  16:  }


As expected this throws a "System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list."

Example using log.DebugFormat()

   1:  try
   2:  {
   3:      if (log.IsDebugEnabled)
   4:      {
   5:          log.Debug("Starting to insert item ABC_1.");
   6:          //Insert item ABC_1
   7:          log.DebugFormat("Item {0} inserted with success. Started inserting item {1}.", "ABC_1");
   8:          log.Debug("Starting to insert item ABC_2.");
   9:          //Insert item ABC_2
  10:          log.Debug(string.Format("Inserted item {0}.", "ABC_2"));
  11:      }
  12:  }
  13:  catch (Exception ex)
  14:  {
  15:      log.Error("Woops", ex);
  16:  }

Using DebugFormat() the logger logs a WARN message, but it doesn't break the application flow.

   1:  WARN StringFormat: Exception while rendering format [Item {0} inserted with
   2:  success. Started inserting item {1}.]


So to avoid logging breaking your application, you should use the DebugFormat(), WarningFormat(), InfoFormat(), ErrorFormat() methods instead of String.Format() to format your log message. This should be a best practice.

Monday, January 11, 2010

"Excellence" is a drive from inside, not outside

A little story I found which I think relates to software development in a way..

A tourist once visited a temple under construction where he saw a sculptor making an idol of God. Suddenly he noticed a similar idol lying nearby. Surprised, he asked the sculptor, "Do you need two statues of the same idol?" "No," said the sculptor without looking up, "We need only one, but the first one got damaged at the last stage." The gentleman examined the idol and found no apparent damage. "Where is the damage?" he asked. "There is a scratch on the nose of the idol." said the sculptor, still busy with his work. "Where are you going to install the idol?" The sculptor replied that it would be installed on a pillar twenty feet high. "If the idol is that far, who is going to know that there is a scratch on the nose?" the gentleman asked. The sculptor stopped his work, looked up at the gentleman, smiled and said, "I will know it."

Can we apply this whole story to software development? No. Often we need to ship the product without it being perfect. Something we can learn from this story is that although the customer does not care about continuous integration, best practices,.. we as developers do should care about everything that isn't visible to the customer.

Wednesday, January 6, 2010

Collection of useful ASP.NET Ajax 4.0 Beta Resources

While playing with the ASP.NET Ajax 4.0 library Beta, I collected a few useful resources. Although I think once the library will be officially released the number of good resources will increase, the list below is certain worthwhile.

The ASP.NET Ajax Library on Codeplex

Yep, this library is open source. Visit the project site to download the latest build.

The official ASP.NET Wiki

An almost complete list of HOW TO's. Use this as a reference.

Whitepapers

E-book: Building high performance web applications

Free e-book focusing on how to use the ASP.NET Ajax 4.0 library to improve the performance of your web applications. Download it for free.

Examples
Bloggers

Monday, January 4, 2010

Customizing Telerik RadGrid tooltips

Today I had to customize the Telerik RadGrid tooltips.

Overriding the hardcoded tooltips

Looking around in the Telerik documentation I found this article. The article shows which properties to use so you can override the hardcoded tooltips.

Being consistent using ASP.NET Themes

It's a best practice to put styles which apply to multiple controls in a Skin using Themes.

This skin looked something like this.

   1:  <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
   2:   
   3:  <telerik:RadGrid 
   4:      runat="server"    
   5:      SortingSettings-SortToolTip="Sorteren"
   6:      PagerStyle-LastPageToolTip="Laatste pagina"                    
   7:      PagerStyle-NextPageToolTip="Volgende pagina"
   8:      PagerStyle-FirstPageToolTip="Eerste pagina" 
   9:      PagerStyle-PrevPageToolTip="Vorige pagina"    
  10:      PagerStyle-PagerTextFormat="Pagina {0}/{1} | Records {2} - {3} | {4} {5} records">
  11:  </telerik:RadGrid>

Don't forget to register the Telerik Assembly!

Localizing the tooltips

ASP.NET WebForms does not provide support to localize Skins.

If you do try you will receive the runtime error "Expressions are not allowed in Skin files" (Been there, done that).

Applying the theme to all RadGrids

I didn't add a SkinID, because I want the skin to apply to all RadGrids without setting the SkinID on every RadGrid. You can simply modify the pages element in your web.config to apply the Theme to your whole webapplication.

   1:  <configuration>
   2:      <system.web>
   3:          <pages theme="ThemeName" />
   4:      </system.web>
   5:  </configuration>