Web Development

Silverlight, Silverlight, Silverlight...and laptops

On the second day of the PDC, Scott Guthrie announced the release of the first beta of Silverlight 4. Well, I've been expecting Silverlight to replace WPF as the first-choice for line-of-business apps for a long time, and I was right. The number of new features is overwhelming. Just look at this comprehensive post written by Tim Heuer to get definitive prove. And as part of this release, they've renamed the RIA Services framework to WCF RIA Services and included it in the Silverlight 4 SDK. Check out this post to get some more info on what has changed since the last CTP. I spend the remainder of the day attending every Silverlight 4 session available. I'm so looking forward to using this in a real-life project.

One thing all attendees noticed this week is that the PDC was going through a crisis as well. There was no free breakfast, no party at Universal Studios and even no gadget. Well, the PDC organization has compensated for that big time. How? Well, because during the keynote, Steven Sinofsky announced that every attendee will receive a multi-touch convertible Acer Aspire 1420P tablet pc for free. Now that's what I call an awesome gadget! And it is fully installed with Windows 7, the Office 2010 beta and some nice showcase tools for its multi-touch support. I can tell you that the audience went wild when this was announced.


Published: 19-11-2009 by Dennis Doomen | 0 Comments | 0 Links to this post
 

Screen captures: going down?

Ever wanted to capture the entire content of a web browser's client area, all the way down to the bottom of the scrollable window? Found yourself cutting and pasting multiple screenshots of the same scrollable web page into one continuous image?
 
Today I got fed up this routine and started looking for a solution; Surely there must be some application that can lighten the burden! Enter FireShot: this FireFox and IE plugin is just what the doctor ordered, and best of all: It's free!
 
FireShot takes snapshots of the entire content or just the visible content and even comes with a simple editor to directly modify a capture. This can be especially usefull for testing and documentation.
 
You can download FireShot here http://screenshot-program.com/fireshot/ or by searching for add-ons in FireFox.

Published: 12-11-2009 by Peter Hesseling | 0 Comments | 0 Links to this post
 

Keeping an eye on your visitors…

When we build an e-commerce site, our customers are really interested who is visiting and what they are doing. A free and really good option to get this kind of information is Google Analytics. Google Analytics gives you all the standard information like how many visitors per day, how many page views, the time spent, where visitors came from and which browser they used.

 Google Analytics Dashboard

But there is more: using the e-commerce, you can get reports on the amount visitors spent on your site and which products they spent it on. Interesting information but you can probably also get this from your ERP system.

But what your ERP probably cannot do is apply the e-commerce data to other data in Analytics, giving you information such as which percentage of my revenue is caused by visitors using Internet Explorer version 7.0, or how much revenue is caused by visitors originating from the Google search engine. You can get all of this information by placing a small piece of java script on all your pages.

Also interesting is that Analytics allows you to segment your visitors on all kinds of data. By default you get segments like new visitors, returning visitors and traffic coming from search sites. But you can also create your own. This way you can create a segment representing all the visitors that bought a specific product.

But wait, there is even more: using simple java script, you can also track all kinds of events. For instance, you can track when people add something to their basket and which product this is, but you can also track downloads for files or any outbound links you might have. As you can see, the possibilities are almost endless.

But there is one thing Analytics doesn’t do and that is give you insight into what is happening on your site now. Google Analytics always has a log of several hours, which makes it impossible to see in real-time if your e-mail campaign is working.

I recently stumbled onto chartbeat, a web based service that does give you real-time insight into what is happening on your site. By placing a small piece of java script on your site, it does some things Analytics doesn’t do: it shows you how many people are on your site, which pages they are visiting, where they are coming from and what they are doing (reading, writing or idle) and more, all in real-time.

 Chartbeat Dashboard

You can also set up e-mail and SMS alerts for such things as when the number of visitors to your site goes above the monthly average or the load time of a page is more than normal.

Chartbeat is not free (only for the first month) but US$ 10 per month is not too much for this kind of information.

Chartbeat and Google Analytics give you valuable insight into what is happening on your site.


Published: 30-08-2009 by Erwin Werkman | 0 Comments | 0 Links to this post
 

Best practice for accessing objects in ASP.NET cache

Fetching data from a webservice or a database can take some time. When it concerns static data that is used often in your application, it is wise to store the data in cache. That way you only have the performance hit of fetching the data once. ASP.NET has a HttpContext.Cache object that can be used to store your data. But what is the best way to read and write data in cache? And how do you handle the situation where multiple users of your web application access the same data in cache? I will try to answer these questions with an example.
Say you have a web application that uses a list of countries. The countries are stored in a database and do not change very often so you want to fetch and store the list in cache. You create a property 'Countries' that handles the fetching and caching of the countries. An obvious solution would be:

   1:  public List<string> Countries
   2:  {
   3:      get
   4:      {
   5:          // Try getting the countries from cache
   6:   
   7:          if (Cache["countries"] == null)
   8:          {
   9:              // Not in cache, so get the countries
  10:              // from the database and store them in cache
  11:              Cache["countries"] = GetCountriesFromDatabase();
  12:          }
  13:   
  14:          return (List<string>)Cache["countries"];
  15:      }
  16:  }

However, this is not a very good solution, because you should never assume objects in cache to be there. The cache can be expired at any time (for example because of a lack of resources). Even right after an object has been stored in cache, it can be removed. If, in the above example, the cache is cleared just before the return statement, the Countries property will incorrectly return null. To solve this, we should use a temporary variable. Like this:

   1:  public List<string> Countries
   2:  {
   3:      get
   4:      {
   5:          // Try getting the countries from cache
   6:          List<string> countries = (List<string>)Cache["countries"];
   7:          if (countries == null)
   8:          {
   9:              // Not in cache, so get the countries 
  10:              // from the database and store them in cache
  11:              countries = GetCountriesFromDatabase();
  12:              Cache["countries"] = countries;
  13:          }
  14:   
  15:          return countries;
  16:      }
  17:  }

This is better, because now it is no longer possible to return null when the cache is cleared. But this solution is not optimal either. What happens when multiple users are using the application at the same time and the Countries property is called from multiple threads simultaneously. When this happens before the cache has been filled it will result in multiple expensive calls to the database, just to get the same list of countries and store it in cache. This will degrade the overall performance. It would be enough to let just one thread fetch the countries and store them in cache. This can be accomplished by using locks:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          lock (CountriesCacheLock)
   8:          {
   9:              // Try getting the countries from cache
  10:              List<string> countries = (List<string>)Cache["countries"];
  11:              if (countries == null)
  12:              {
  13:                  // If not available from cache, apply a lock to fill the
  14:                  // cache in a thread-safe way. This avoids that multiple 
  15:                  // threads will simultaneously fetch the same list of
  16:                  // countries from the database
  17:                  countries = GetCountriesFromDatabase();
  18:                  Cache["countries"] = countries;
  19:              }
  20:   
  21:              return countries;
  22:          }
  23:      }
  24:  }

With the lock in place only one thread at a time can access the implementation of the Countries property, so there will be no more simultaneous calls to get the countries from the database. And still this is not an optimal solution, because now multiple threads must wait for each other before they can read the cache which is a loss of performance. Reading a value from cache is a thread-safe operation and could therefore be done by multiple threads at the same time. So the reading of the cache should be moved outside the lock:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          // Try getting the countries from cache
   8:          List<string> countries = (List<string>)Cache["countries"];
   9:          if (countries == null)
  10:          {
  11:              lock (CountriesCacheLock)
  12:              {
  13:                  // If not available from cache, apply a lock to fill the
  14:                  // cache in a thread-safe way. This avoids that multiple 
  15:                  // threads will simultaneously fetch the same list of
  16:                  // countries from the database
  17:                  countries = GetCountriesFromDatabase();
  18:                  Cache["countries"] = countries;
  19:              }
  20:          }
  21:   
  22:          return countries;
  23:      }
  24:  }

But now we are back to the performance issue of multiple threads accessing the Countries property when the cache has not been filled. In such situation, the first thread will apply the lock en start the time consuming operation of fetching the list of countries. Threads that in the meantime access the Countries property will have to wait for the lock to be released. But when that happens each thread that has been waiting for the lock will still go and fetch the list of countries again. For this to work more efficiently we will have to check again if the cache has been filled within the lock. Only if the cache is still empty we have to do the expensive database call. The final solution now looks like this:

   1:  private readonly object CountriesCacheLock = new object();
   2:   
   3:  public List<string> Countries
   4:  {
   5:      get
   6:      {
   7:          // Try getting the countries from cache
   8:          List<string> countries = (List<string>)Cache["countries"];
   9:          if (countries == null)
  10:          {
  11:              // If not available from cache, apply a lock to fill the
  12:              // cache in a thread-safe way. This avoids that multiple
  13:              // threads will simultaneously fetch the same list of
  14:              // countries from the database.
  15:              lock (CountriesCacheLock)
  16:              {
  17:                  // Try getting the countries from cache again, because the
  18:                  // cache might have been filled while waiting for the lock
  19:                  countries = (List<string>)Cache["countries"];
  20:                  if (countries == null)
  21:                  {
  22:                      // If still not in cache, get the countries 
  23:                      // from the database and store them in cache
  24:                      countries = GetCountriesFromDatabase();
  25:                      Cache["countries"] = countries;
  26:                  }
  27:              }
  28:          }
  29:   
  30:          return countries;
  31:      }
  32:  }

See also:
http://stackoverflow.com/questions/39112/what-is-the-best-way-to-lock-cache-in-aspnet


Published: 10-03-2009 by Martin Opdam | 0 Comments | 0 Links to this post
 

AJAX 'loading…' animated GIF images

When you are building a nice-looking AJAX enabled website, you probably need some cool animated GIF images to indicate that the website is busy processing. But how do you create these images? Of course you can search the web for an image that just suits your needs, but what are the odds of finding an image that just fits your needs and matches your website’s style.

That’s when websites like ajaxload.info or Load info come in handy. Here you can create your own custom animations. You can choose a indicator type, color and background color, and an animated GIF will be generated for you. Right-click, ‘Save picture as…’ and you’re done.

clip_image001


Published: 17-01-2009 by Martin Opdam | 0 Comments | 0 Links to this post
 

The art and science of performance analysis

Assessing an application’s performance has – at least in the past – been more of an art than a science. Experts in this field are true wizards who choose their performance metrics in mysterious ways and by magic churn out reports which will make or break your reputation as a quality software developer.

Although many developers acknowledge the importance of building to pre-defined performance standards, very few actually perform the appropriate tests to verify that their software actually adheres to those standards. Most often this is due to a lack of understanding of performance metrics and how to analyze them.

For all those developers who want to measure and analyze the performance of their applications but just don’t know where to start: Take a look at the Performance Analysis of Logs (PAL) Tool. This tool reads in a performance monitor counter log and analyzes it using complex thresholds. The tool generates a report which graphically charts important performance counters and throws alerts when thresholds are exceeded. The generated report not only tells you whether thresholds are exceeded but it also explains why a specific threshold is important and which performance counters are involved in the analysis.

Report Graph

Generated reports come complete with illustrative charts

Report Thresholds

Alerts are highlighted in the report

The PAL tool comes complete with threshold files for all major Microsoft products such as IIS, MOSS, SQL Server, BizTalk, Exchange, and Active Directory. In addition it enables you to create your own threshold files to analyze any performance counter you want.

You can check out the tool on CodePlex:

http://www.codeplex.com/PAL


Published: 29-01-2008 by Peter Hesseling | 0 Comments | 0 Links to this post
 

Invalid postback or callback argument. Event validation is enabled using

Everseen the following error:
Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

 

Well our team has seen this error quite a few times the last two days. On every screen where we had a gridview with buttons that were databinded, it appeared after we pushed the button.

Situation:

We have a list of orders and when we push the delete button we want a order from the list to disappear from our datastore as well as our screen.

Pretty straight forward, our implementation however had some quirks which we thought we had resolved them by databinding the GridView everytime the control was being posted. So in every Page_load the gridview.databind(); was being called, this worked for us for the last couple of months. Last week however this stopped working, don't ask me why it just did.

Our solution:

Make sure that you only do a databind() on the gridview in the !Page.IsPostBack part of your page_load. This way your gridview has its datasource binded and wil keep the information in its viewstate.

Now when you press the button on your gridview

- Handle the event, ie Delete item from datastore

- Reset your datasource of the gridview to reflect the changes to your datastore

- Call DataBind() on your gridview.


Published: 23-11-2007 by Hans ter Wal | 0 Comments | 0 Links to this post
 

SilverLight 1.1 Developer Reference poster

I haven't had a lot of time to investigate SilverLight yet, but if you haven't heard of it, I'm afraid you've been living in a cave for the last couple of months. Anyway, check out this great poster (click here get a full-size version).
 

Published: 24-05-2007 by Dennis Doomen | 0 Comments | 0 Links to this post