Monday, December 21, 2009

Looking back, moving forward (New years post)

In this post I'm going to reflect on the year that's almost finished and the year to come.

I came up with a few topics that are worth discussing in this post.

My career

I don't think I ever mentioned where I work. The first of January I will be working 18 months for Ferranti. The only company I've worked for since I graduated.

The first project I've ever worked on was a rather big one. Firestation Antwerp. Last year we heard that sales scored another firestation for us (Firestation Ghent). So I've been working on these two projects since I started.

Do these projects get boring? Well, not boring, exhausting maybe. These projects are very complex (Dispatching, telecommunication, websites, GIS, ..) and the requirements are very high. Although these projects are exhausting from time to time, I don't think there are other projects where I would've learned as much in such a small period of time. As a developer I have touched and worked on lots of stuff: ASP.NET, WindowsServices, WCF, WebServices, GIS, API's, Telecommunication.. You name it.

Because I've had the chance to play with so many things I'm pretty sure that web development fits me best. So next year I will try to mainly focus on web developement.

Blog

I think I've been blogging since October 2008. When I just started out the quality of the content was rather poor. Although I'm not totally satisfied with the content I produced this year, I hope the quality has improved noticeable. I saw the traffic increase significantly this year, so I hope that's a good sign.

There are a few posts that scored pretty good out there. You can find them here. I'd like to thank Arjan Zuidhof, Lee Dumond, Alvin Ashcraft, .. for helping me getting my blog out there.

By blogging I've made lots of new friends. I enjoy reading through all of your Tweets. Bart De Smet in particular has been a very good mentor.

Community

I managed to go to two events this year:
- TechDays Belgium
- Scott Guthrie in Belgium

I hope I will get the opportunity to go to some big event next year. I also plan on going to more VISUG sessions.

I've been neglecting the ASP.NET forums lately. In general I think the quality of the questions is rather poor and there are plenty of good answerers. I've been a long time StackOverflow lurker. Next year I'll try to contribute to that community.

Travelling

I managed to travel four times this year:

In 2010 I'll try to go abroad at least three times.

Wrap up

In general, my year was pretty fun. I hope 2010 will be at least as good. Excited about hearing how you did this year and what you hope to achieve in 2010!

Thursday, December 17, 2009

Sunday, December 13, 2009

The problem that ViewStateMode solves

A new feature of ASP.NET 4.0 is the ViewStateMode property on a Control.

You can use the ViewStateMode property to enable view state for an individual control even if view state is disabled for the page.
Source:Msdn

In this post I'll try to give this new feature a chance to shine and show it's use.

Problem to solve: Disable ViewState on the Page and enable it on an individual Control.

Let's try to solve this without the ViewStateMode property. Simply disable the ViewState on the page and enable it on lblViewstate1.

   1:  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ViewState_3_5.aspx.cs" Inherits="Demo_2___ViewState.ViewState_3_5" 
   2:      EnableViewState="False"%>
   3:   
   4:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5:   
   6:  <html xmlns="http://www.w3.org/1999/xhtml">
   7:  <head runat="server">
   8:      <title></title>
   9:  </head>
  10:  <body>
  11:      <form id="form1" runat="server">
  12:      <div>
  13:          <asp:Panel runat="server" ID="pnViewState">
  14:              <asp:Label runat="server" Text="[Static value]" ID="lblViewState1" EnableViewState="True"/>
  15:              <asp:Label runat="server" Text="[Static value]" ID="lblViewState2"/>        
  16:              <asp:Button runat="server" Text="Do PostBack" ID="btnDoPostBack" onclick="btnDoPostBack_Click" />
  17:          </asp:Panel>
  18:      </div>
  19:      </form>
  20:  </body>
  21:  </html>

   1:  protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:       if (!Page.IsPostBack)
   4:       {
   5:           this.lblViewState1.Text = "[Dynamic value]";
   6:           this.lblViewState2.Text = "[Dynamic value]";
   7:       }
   8:  }
   9:   
  10:  protected void btnDoPostBack_Click(object sender, EventArgs e)
  11:  {
  12:      //Do Postback
  13:  }

Hmmm this doesn't work. When I click the button and do a PostBack the Label lblViewState1 didn't maintain it's state. It displays [Static value] instead of [Dynamic value].

You could solve this problem by enabling the ViewState on the Page and disable the ViewState on all Controls that don't need to maintain their state. But that's pretty silly right?

This is where the ViewStateMode property comes into play. Check out the example below. I disable the ViewStateMode on the Page and I enable the ViewStateMode on lblViewState1.

   1:  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ViewState_3_5.aspx.cs" Inherits="Demo_2___ViewState.ViewState_3_5" 
   2:      EnableViewState="True" ViewStateMode="Disabled"%>
   3:   
   4:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5:   
   6:  <html xmlns="http://www.w3.org/1999/xhtml">
   7:  <head runat="server">
   8:      <title></title>
   9:  </head>
  10:  <body>
  11:      <form id="form1" runat="server">
  12:      <div>
  13:          <asp:Panel runat="server" ID="pnViewState">
  14:              <asp:Label runat="server" Text="[Static value]" ID="lblViewState1" ViewStateMode="Enabled"/>
  15:              <asp:Label runat="server" Text="[Static value]" ID="lblViewState2"/>        
  16:              <asp:Button runat="server" Text="Do PostBack" ID="btnDoPostBack" onclick="btnDoPostBack_Click" />
  17:          </asp:Panel>
  18:      </div>
  19:      </form>
  20:  </body>
  21:  </html>

After doing a PostBack lblViewState1 still shows [Dynamic value] and lblViewState2 shows [Static value]. lblViewState1 maintained it's state!

This feature gives us another reason to stop being lazy and use ViewState where it's designed for.

Hope this helps.

Monday, December 7, 2009

Add leading zeros to a number

Todays post is a very small tip.

I saw the question "How to add leading zeros to a number" on the ASP.NET forums countless times before. And often the answers provide solutions that work, but are overkill as well.

The two cleanest methods I know are String.Format and PadLeft.

   1:  Console.WriteLine("Using .ToString()");
   2:  Console.WriteLine(String.Format("{0:0000}", 16));
   3:   
   4:  Console.WriteLine("-------------------");
   5:   
   6:  Console.WriteLine("Using .PadLeft()");
   7:  Console.WriteLine(Convert.ToString(16).PadLeft(4, '0'));

You can see the result here.

//Using .ToString()
//0016
//-------------------
//Using .PadLeft()
//0016

Saturday, December 5, 2009

Response.RedirectPermanent in .NET 3.5 and older

One of the new features in ASP.NET 4.0 is permanently redirecting to a page using Response.RedirectPermanent.

It is common practice in Web applications to move pages and other content around over time, which can lead to an accumulation of stale links in search engines. In ASP.NET, developers have traditionally handled requests to old URLs by using by using the Response.Redirect method to forward a request to the new URL. However, the Redirect method issues an HTTP 302 Found (temporary redirect) response, which results in an extra HTTP round trip when users attempt to access the old URLs.
Source


You can achieve this functionality in ASP.NET 3.5 and older by writing a 301 Moved Permanently Status and a Location Header to the Response stream. This can be found in the HTTP specifications.

Here is an example.


   1:  Response.Clear();
   2:  Response.Status = "301 Moved Permanently";
   3:  Response.AddHeader("Location", "PageOne.aspx");
   4:  Response.End();



You can verify this by using Fiddler.

Scott Guthrie in Belgium #ScottInBelgium

Yesterday Belgium had the honor to welcome Scott Guthrie.

Scott gave three sessions in Kinepolis Brussels (next to the Atomium and the King Baudouin Stadium) on:
  • Visual Studio 2010 and .NET 4.0 Web development
  • Silverlight
  • ASP.NET MVC 2

Due to some personal obligations and traffic jams in Brussels I had to leave after the first session. So you'll only find my impressions of the first session..

Visual Studio 2010 and .NET 4.0 Web development

Scott demoed some of the neatest Visual Studio 2010 features and improvements. I blogged on some of them here. Neat stuff I don't talk about in that post are:

After finishing up the Visual Studio demo, he continued with demoing ASP.NET 4.0 Web development. If you missed this session, I suggest you read this whitepaper!

Conclusion

All by all it was a very interesting session. It was definitely worth driving to Brussels for. Something extra which will make me think of this session everytime I open my closet is the famous Gu red shirt we all received.



If other Belgian bloggers blogged on this event as well please contact me so I can add a link to your post!
Update 1: Katrien blogged on this event as well. She was lucky enough to make it to all sessions. See her post here.
Update 2: Another post by Gill Cleeren on this event.

Tuesday, November 17, 2009

Book review: Professional Refactoring in C# & ASP.NET

Three months ago I was looking up to refactoring a legacy ASP.NET Webforms application. Although I was familiar with refactoring, I ordered "Professional Refactoring in C# & ASP.NET" by Daniejel Arsenovski to get deeper into refactoring.

The title

Although the title states "Professional", I think this book should find it's main audience in coding novices. Another problem with the title is the word ASP.NET in it. The book has one chapter covering ASP.NET, with only 35 poor-quality pages in it.

Now the title has some issues, but how was the content?

The content

Danijel identifies codesmells and shows refactoring techniques to solve them. Too bad some of these examples are spreaded over multiple pages, which makes them a tad sloppy and hard to read. Danijel stresses how important Object Oriented design is. He proves this by transforming procedural code into Object Oriented code, greatly improving the readability. This book should help developers who are new to or come from a non-OO background to apply the basic Object Oriented concepts. Next to refactoring techniques, he also touches refactoring tools, unit testing and design patterns.

I think the beginning .NET developer might be able to significally start improving his codebase by reading this book. For more experienced .NET developers most of the topics handled in the book should be part of their day-to-day skillset.

Conclusion

All by all I was a bit dissapointed by the book, it was an easy read, had a few interesting tricks, but I expected it would go more into depth.

Something valuable I realised though.. is that refactoring isn't something you learn by reading a book, but you learn it by obeying the constant hunger for improving your code.

If you feel confident that you dig the basic concepts of writing quality code, I would instead of buying this book, invest in a good book on Object Oriented concepts or design patterns.






Monday, November 9, 2009

My trip to Madrid in ten pictures

Last week I went to Madrid with my family-in-law to visit my girlfriend's brother and cousin.

Although our stay there was rather short (only four days), we visited some of the most impressive places in Madrid:
- Stadium Real Madrid
- The Royal Palace
- Prado Museum
- Queen Sofia Museum
- Buen Retiro Park
- Plaza Mayor
- ...


As always my girlfriend took lots of pictures, you can find my favorites below. Enjoy :)

Stadium Real Madrid



Pay attention to the stitching "Jesus in first place"


Royal Palace





Ruïnes of an Egyptian temple



Buen Retiro Park




Older lady feeding the birds. I wonder what her trick is.. Four of us tried letting them eat out of our hands, but we all failed.


Sunday, November 1, 2009

Walking through a new Web Application in Visual Studio 2010 (.NET 4.0)

Although I installed Visual Studio 2010 Beta 2 the first day it came out, today was the first day I made a new Web Application. In this post I will walk you through creating a new Web Application in Visual Studio 2010. I'll show you what's new and what's different.

Creating a new Web Application



Create new project

After clicking the New project link, you will see an improved Project Template window.

Search for the Web node in the Project Templates tree. You might notice that there are three new Project Templates: Empty ASP.NET Web Application, ASP.NET Web Application and ASP.NET MVC 2 Web Application.

In this post I'll show the ASP.NET Web Application template.



Select ASP.NET Web Application

New stuff in the this template

When you look at the Solution Explorer, you will notice that there more default folders and pages. Let me walk you through them.



Solution Explorer

New references

There are some new default references.

1: Microsoft.CSharp
The Microsoft.CSharp namespace contains classes that support compilation and code generation using the C# language.
Source: Msdn


2: System.Web.ApplicationServices
The System.Web.ApplicationServices namespace provides classes that enable you to access ASP.NET forms authentication, roles, and profiles application services as Windows Communication Foundation (WCF) services.
Source: Msdn


3: System.Web.DynamicData
The System.Web.DynamicData namespace contains classes that provide the core functionality for ASP.NET Dynamic Data. It also provides extensibility features that let you customize dynamic data behavior.
Source: Msdn


The Account folder

This folder holds a few default pages that provide default membership functionality. Yes, that's right, a membership provider is baked in this template.



The Login page



The Register page

The App_Data folder

In this folder you will find the membership database.

The scripts folder

This folder holds the jQuery(!) javascript files. Yep jQuery is now even shipping with Web Forms out of the box.

Styles

Here you will find the CSS file that's used throughout the web application.

Wonder where the Webforms team got their inspiration from ;)



The default style

The Default and About page

The Default.aspx page has been here forever, but the About.aspx page is new. And it does exactly what you think it does. You can supply some information about you or your application in this page.

Global.asax

The Global.asax is there by default. A nice feature that has been added are inline comments that help you understand the most common application events.



   1:  namespace MyFirstWebApplication
   2:  {
   3:      public class Global : System.Web.HttpApplication
   4:      {
   5:   
   6:          void Application_Start(object sender, EventArgs e)
   7:          {
   8:              // Code that runs on application startup
   9:   
  10:          }

  11:   
  12:          void Application_End(object sender, EventArgs e)
  13:          {
  14:              //  Code that runs on application shutdown
  15:   

  16:          }
  17:   
  18:          void Application_Error(object sender, EventArgs e)
  19:          {
  20:              // Code that runs when an unhandled error occurs
  21:   
  22:          }
  23:   
  24:          void Session_Start(object sender, EventArgs e)
  25:          {
  26:              // Code that runs when a new session is started

  27:   
  28:          }
  29:   
  30:          void Session_End(object sender, EventArgs e)
  31:          {
  32:              // Code that runs when a session ends. 
  33:              // Note: The Session_End event is raised only when the sessionstate mode
  34:              // is set to InProc in the Web.config file. If session mode is set to StateServer 
  35:              // or SQLServer, the event is not raised.

  36:   
  37:          }
  38:   
  39:      }

  40:  }


Site.Master

A default master page comes with the template as well.

Conclusion

Although I rather will use the Empty ASP.NET Web Application, I think this template is a great effort to push best practices to the novice Web Forms developer. This template helps you getting started with the most powerful features of Webforms.

What are your thoughts on this new template? Will you use it?

Saturday, October 24, 2009

Linqify your legacy webapplications: five real-world refactor examples

Edit notes:
- Edited examples based on Bart's feedback (see comments).

This post is meant for developers who are upgrading legacy webapplications to .NET 3.5 and for developers who know Linq, but have a hard time finding scenarios to apply Linq.

I got my inspiration for this post by reading Professional Refactoring in C# & ASP.NET (Wrox Programmer to Programmer).

I downloaded the My Web Pages Starter Kit to find some examples, which is written for .NET 2.0. I upgraded it to .NET 3.5 to use Linq.

Below you can find some real-world examples of refactoring to use Linq.

Querying collections never has been this clean!


Example one

Before

   1:  bool blnTravelDiary = false;
   2:  foreach (string theme in themes) {
   3:      if (Path.GetFileName(theme) == "TravelDiary")
   4:              blnTravelDiary = true;
   5:  }


After

   1:  bool blnTravelDiary = themes.Any(theme => Path.GetFileName(theme) == "TravelDiary"); 



Example two

Before

   1:  foreach (RoleData data in _roles) {
   2:      if (data.RoleName.Equals(roleName, StringComparison.CurrentCulture))
   3:              return true;
   4:  }
   5:  return false;


After

   1:  bool exists = _roles.Any(roleData => roleData.RoleName.Equals(roleName, StringComparison.CurrentCulture));



Example three

Before

   1:  foreach (RoleData data in _roles) {
   2:      if (data.RoleName == rolename) {
   3:              found = data;
   4:                      break;
   5:           }
   6:  }

   7:  return found;


After

   1:  var found = from RoleData data in _roles
   2:              where data.RoleName == rolename
   3:              select data;
   4:  return found.FirstOrDefault();



Example four

Before

   1:  List<string> foundRoles = new List<string>();
   2:  foreach (RoleData data in _roles){
   3:      if (data.Users.Contains(username))
   4:              foundRoles.Add(data.RoleName);
   5:  }
   6:  return foundRoles.ToArray();


After

   1:  var data = from RoleData roleData in _roles
   2:             where roleData.Users.Contains(username)
   3:             select roleData.RoleName;
   4:  return data.ToArray();



Example five

Before

   1:  foreach (MembershipUser user in Membership.GetAllUsers())
   2:  {
   3:      if (string.Compare(user.UserName, txtUserName.Text, true) == 0)
   4:          {
   5:              Login1.UserName = user.UserName;
   6:                     return;
   7:          }
   8:  }



After

   1:  var matchingUsers = from MembershipUser user in Membership.GetAllUsers()
   2:                      where string.Compare(user.UserName, txtUserName.Text, true) == 0
   3:                     select user.UserName;
   4:   
   5:  var firstMatch = matchingUsers.FirstOrDefault();
   6:   
   7:  if (firstMatch != null) {
   8:      Login1.UserName = firstMatch;
   9:  }

Friday, October 23, 2009

The evolution of the Windows desktop in images, from Windows 3.1 To Windows 7.

@CodingHorror: I can't deal with Chrome themes or Windows 7 themes... at all. Give me plain, simple, clean, and uncluttered. kthxbye

Jeff Atwood tweeted this a few days ago. This triggered me to assemble a list of Windows desktops, from Windows 3.1 to Windows 7.

I also don't think the extra UI stuff in Windows Vista and Windows 7 add extra value. I'm still a big fan of the simple Windows XP UI.

Which one do you like best? Is there to much clutter in the new interfaces?

Check out the list of images below to see the evolution of the Windows desktop.

Windows 3.1


Windows 3.5


Windows 3.51


Windows 4


Windows 95


Windows 98


Windows 2000


Windows XP


Windows Vista


Windows 7



Sunday, October 18, 2009

Building a simple Twitter widget using TweetSharp and ASP.NET

Widgets are a great way to spread your content. Users can just copy and paste some simple HTML or JavaScript, and off they are. By embedding this HTML or JavaScript, content is loaded from another server. Perfect examples are Google ads and Amazon ads.

I wondered how hard it could be. That's why I wrote a small Twitter widget using ASP.NET and TweetSharp. This widget simply shows your Tweets. To keep things simple it's HTML hosted in an iFrame. This solution might be a scalability nightmare tho, because it's executing the code every time the page loads.

When finished the widget looked something like this.



Let's take a look how you can build your own.

Get tweets by username

I used the very Elegant TweetSharp API for this.



   1:  private IEnumerable<TwitterSearchStatus> GetStatuses(string screenName) {
   2:       var twitter = FluentTwitter.CreateRequest().
   3:                                  Search().Query().FromUser(screenName);

   4:       return twitter.Request().AsSearchResult().Statuses;
   5:  }      



Build the widget

This method builds the HTML. I used the HtmlTextWriter class for this. A safe way to build HTML.


   1:   private String BuildWidget(string username, IEnumerable<TwitterSearchStatus> statuses) {
   2:              StringWriter stringWriter = new StringWriter();
   3:              
   4:              using (HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter)) {
   5:                  htmlWriter.RenderBeginTag(HtmlTextWriterTag.B);
   6:                  htmlWriter.Write("My tweets");

   7:                  htmlWriter.RenderEndTag();
   8:   

   9:                  htmlWriter.RenderBeginTag(HtmlTextWriterTag.Div);
  10:                  htmlWriter.RenderBeginTag(HtmlTextWriterTag.Ul);
  11:   
  12:                  foreach (var status in statuses) {
  13:                      htmlWriter.RenderBeginTag(HtmlTextWriterTag.Li);
  14:   
  15:                      htmlWriter.Write(String.Format("({0})", status.CreatedDate.ToString("hh:mm")));
  16:                      htmlWriter.Write(" ");
  17:                      htmlWriter.Write(status.Text);
  18:                      
  19:                      htmlWriter.RenderEndTag();
  20:                  }           
  21:   
  22:                  htmlWriter.RenderEndTag();
  23:   
  24:                  htmlWriter.AddAttribute(HtmlTextWriterAttribute.Href, "http://twitter.com/" + username);                
  25:                  htmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
  26:                  htmlWriter.Write("Follow me");
  27:                  htmlWriter.RenderEndTag();
  28:   
  29:                  htmlWriter.RenderEndTag();
  30:              }
  31:   
  32:              return stringWriter.ToString();             
  33:          }



Writing the widget to the page

On the Page_Load event of the Page I get the username from the QueryString, get the statuses for this username, pass them to the BuildWidget method and write that result to the Reponse Stream.


   1:  protected void Page_Load(object sender, EventArgs e) {
   2:              string username = Request.QueryString["username"];;
   3:              if (!String.IsNullOrEmpty(username)) {
   4:                  Response.Write(BuildWidget(username, GetStatuses(username)));
   5:              }
   6:          }



Embedding the widget in a page

I hosted the widget in an iFrame. Set the src attribute of the iFrame to the url of your widget.


   1:  <div style="width:30%;height:100%;float:right"> 
   2:              <iframe scrolling="yes" 
   3:                  style="" 
   4:                  frameborder="1" 
   5:                  src="http://localhost:1524/TwitterWidget.aspx?username=JefClaes" 
   6:                  marginheight="0" 
   7:                  marginwidth="0">
   8:              </iframe> 
   9:          </div> 



That was pretty easy right?

Get the source.

Saturday, October 17, 2009

Format your code using Syntax Highlighters

Yesterday I asked on Twitter if it bothers people that I use screenshots for codesnippets, and Lee Dumond honestly answered that screenshots suck.

Well he is right. On my monitor the screenshots look pretty good, but on laptops/smaller monitors they aren't handy at all.

Today I looked for Syntax Highlighters. Looks like there are two big players in the syntax highlighting business, and a few smaller ones.

I made a summary of interesting Syntax Highlighters I found. I will be experimenting with those in the coming weeks.

If you use one that isn't in this list, please let me know by leaving a comment!

(Edit: Don't forget to scroll to look at the list of supported languages and features!)

Saturday, October 10, 2009

Is this something the blogosphere could use?

Social networking is one of the core elements to promote your blog.

I can imagine that this becomes a hassle if you are a professional blogger and have to promote multiple blogs. Technology is able to bring a solution offcourse.

What you see below is a picture of the PostBroadcaster. The PostBroadcaster is a service which keeps an eye on your Rss feed, and as soon as it sees an update in your Rss feed, it broadcasts this to multiple social networking sites.



Please give me your opinion. Could this be "something"?

Friday, October 2, 2009

RSS in .NET

A few days ago, I was playing with some RSSFeeds.

As far as I knew, I had to build an HttpWebRequest, get the HttpWebReponse and parse the response. While searching for the RSS defenition, I realised that this must have been done 1000 times before.

I googled RSS .NET and found one relevant link to a dead/failed open source project. Looking further I came across some articles which used an XmlReader and LinqToXml, but this wasn't what I was looking for. I asked whether there is any good RSS library in .NET at StackOverflow, and one smart guy pointed me to the System.ServiceModel.Syndication namespace. This is new in .NET 3.5 and after looking around some more I found out that it's a pretty unknown namespace.

After playing with it for 15 minutes I was pretty sure this was exactly what I was looking for.

Reading and creating RSS has never been this easy/safe.
You can find how to read an RSS Feed an how to create a new RSS Feed below.

Reading an RSS Feed




Create an RSS Feed




Pretty simple right?

Download the source.

Tuesday, September 22, 2009

Video: Road to Redmond (Dutch)

A while ago I got to know Dandy Weyn and Bart De Smet through Facebook. These two people have something in common, which gave me an idea. They both work for Microsoft in Redmond and were born in Belgium.

I thought doing a double-interview might give me some great content for my blog. I contacted them and told them about my idea. They both embraced the idea and took it to another level. They took the time to make a video and show what's life like up there.

The video turned out to be really funny. While talking about what it takes to travel the road to Redmond, they go off-topic a lot, which leads to some good lolz.

Enjoy!




Dandy and Bart, thanks a lot for doing this!

Don't forget to visit Bart's blog.

Saturday, September 12, 2009

Why the javascript beforeunload event is incomplete

The onbeforeunload event fires when a page is being unloaded.

In the intranet webapplications world customers pretty often ask to show a warning when a user leaves a page (by closing the browser, closing a tab, clicking a link,..). This feature is specifically very interesting for data-input-driven webforms where one wrong click can make ten minutes of work undone.

Last week I had to implement this feature in a huge webform which is causing lots of postbacks (firing the onbeforeunload event). Actually I only had to warn the user when they closed the browser or clicked a link in the masterpage. I figured out that the beforeunload event must have some convenient properties, but as you can see below, it had no properties which I could use.



Offcourse there are workarounds for this problem, like there are workarounds for almost all technology problems. But these workarounds often make tasks harder and less "clean".

In my opinion the browsers could and should do something about this. Adding a few properties like unloadedbysrc, unloadedbytag, unloadedbyid would make our life a tad easier.

What do you think?

Wednesday, September 9, 2009

Debugging "SubReport could not be shown."

I've been upgrading a local report which contains multiple subreports, and yes I got that "SubReport could not be shown." error more than once.

Debugging this error is a pain in the a.. All you get is "SubReport could not be shown.", making me want to punch my screen and scream "BUT WHY?"

Just before breaking my screen and going on full tilt, I decided to take a step back and run through my checklist.

Here it goes..

Can the reportviewer find the subreports?

If the subreports are in another location (other folder, other assembly..), the reportviewer will not find them.

The solution for this problem is using the LoadReportDefinition method and passing the report definition as a stream. An example can be found in this post.

Are you passing all parameters?

Doublecheck your report parameters.

Are you passing all the required/correct data to the report?

Are you handling the SubReportProcessing event, to pass the data to the subreports, not the main report?

Did the database definition change? Did a query break? Is the structure of the query still the same as defined in your report definition?

Are there other things to add to this list?

Tuesday, September 8, 2009

Three common mistakes you should avoid when starting with Web Page Resources in ASP.NET

This is a list of of three common mistakes made by developers who start using Web Page Resources in ASP.NET.

1. Not using the right format for the name of a local resources file

The format of the name of a local resources file should be: PageName.PageExtension.resx.

If you don't add the page extension (Aspx, Ascx), you will get the Exception "The resource object with key 'PageTitle' was not found.".

2. Not adding an App_LocalResources folder to each subfolder

Each subfolder must have it's own App_LocalResources folder, else ASP.NET will not be able the find the resource, leading to the "The resource object with key 'PageTitle' was not found." Exception again.

3. Not understanding the difference between GlobalResources and LocalResources

In general global resources should be used when you need a resourcekey in multiple pages through your site. Local resources are page-specific.

This article on MSDN contains a great summary.

You can use any combination of global and local resource files in the Web application. Generally, you add resources to a global resource file when you want to share the resources between pages. Resources in global resource files are also strongly typed for when you want to access the files programmatically.

However, global resource files can become large, if you store all localized resources in them. Global resource files can also be more difficult to manage, if more than one developer is working on different pages but in a single resource file.

Local resource files make it easier to manage resources for a single ASP.NET Web page. But you cannot share resources between pages. Additionally, you might create lots of local resource files, if you have many pages that must be localized into many languages. If sites are large with many folders and languages, local resources can quickly expand the number of assemblies in the application domain.

When you make a change to a default resource file, either local or global, ASP.NET recompiles the resources and restarts the ASP.NET application. This can affect the overall performance of your site. If you add satellite resource files, it does not cause a recompilation of resources, but the ASP.NET application will restart.

Monday, September 7, 2009

Web Page Resources in ASP.NET: CheatSheet

The four most used functions/expressions when working with Web Page Resources in ASP.NET.



More on Web Page Resources in ASP.NET on MSDN.

Tuesday, September 1, 2009

Disable all validation in a Page

In some scenario's you want to disable all the validation in your page.

You could set the CauseValidation property of the buttons causing postbacks.

But what I did was loop through all the Page Validators and disable them.

Here is a codesnippet.



A small tip, but hope it helps.

Sunday, August 23, 2009

Why codereviews should be a teamthing

Often codereviews are done by one person, the technical lead of your team.

In my opinion it's better to make each developer of your team do codereviews.

My arguments

1. Having all developers doing codereviews enforces well-documented codingstandards..
2. Which also leads to discussions about what these codingstandards should be.
3. Each developer is forced to understand the workflow of an application which isn't his, which expands his domain knowledge.
4. Each developer learns from others and is given an opportunity to teach and discuss why someone chose a certain path.. There is always something new to learn, even for seasoned developers. You might just pick up that latest trick doing whizbang Silverlight 3 stuff from that freshman that just started working this year.
5. Multiple perspectives on a problem can only benefit the outcoming solution.

What are your thoughts?

Thursday, August 20, 2009

My holiday in France in five pictures

Last week I went on a holiday to France with my girlfriend and her family.

Because pictures say more than words..

One: The location - Laguepie, Albi



Two: The house and "la piscine"



Three: Me enjoying the sun



Four: Only in France you find a 1955 Peugeot 403 with numberplates just standing there next to the road



Five: Random picture of one of the towns next to Laguepie



Looking forward to the next holiday :)

Monday, August 17, 2009

Book review: Screwed - The Truth About Life as a Prison Officer



My name is Ronnie Thompson. Being a Prison Officer for Her Majesty's Prison Service was something I used to be proud of. I soon realised the truth of what it's like working as a screw. A fucking headache. The pressures, duties, life-wrecking conditions, danger - none of this is known to the public, but all of it makes up a day in the life of a Prison Officer.


My thoughts

Ronnie takes you on a tour through the whole prison system, giving you a detailed look into the - rotten - real system. This is not what you see in movies or read in the paper. His critical view on the inside together with lots of funny, weird and awesome anekdotes make this book a must-read!

Get the book - Screwed: The Truth About Life as a Prison Officer

Sunday, August 16, 2009

Book review: Hell's Angel



This book is the biography of Ralph 'Sonny' Barger. Sonny is one of the cofounders off the Hells Angels.

You should read this book when..
- you are interested in the history of the Hells Angels
- you like to know their side of the story of their crime history
- you like hearing tough stories at the bar
- you are into biking
- you enjoy freedom

In general I enjoyed reading this book. Some parts where a bit boring, but the most anekdotes were awesome!

Get the book - Hell's Angel: The Life and Times of Sonny Barger and the Hell's Angels Motorcycle Club

Saturday, August 1, 2009

Managing UserControls using Interfaces

It's a pretty common situation where you have multiple UserControls in a page which all expose the same functionalities.

In the project I'm working on right now, we have a big TabContainer. And each Tab is a UserControl. One button should make all the Tabs save their data, but not every Tab is always loaded into the TabContainer. As you can guess, we needed something generic.

That's why I introduced the ITab interface. Every UserControl implements this interface.

When I hit that save-button, a method iterates trough the ControlCollection and looks for every type that implements the ITab interface.

Take a look at this codesnippet.



The public method Iterates through the ControlCollection and checks if the Type is a Tab using the private IsTab() method. This private method uses Type.GetInterfaces() to iterate through all the Interfaces for that Type. If the control is a Tab, I cast it to an ITab and call a public method depending on the ReportMode.

Friday, July 31, 2009

Getting rid of the Formview templates

Having a readonly-mode and an edit-mode in a webform to manipulate data is a pretty common situation.

Microsoft promotes using the FormView control. This might be a good idea when there's not a lot of data to edit, and when the readonly-mode is very different from the edit-mode. But what I mostly see is that the readonly-mode is a copy of the edit-mode with some controls disabled, which is a pain in the ass to maintain.

That's why I got rid of the FormView!

I made a method which can be called from any page/usercontrol and which recusively searches the ControlCollection and sets the Enable-property for some controls.

Take a look at this codesnippet.



This method iterates through the ControlCollection and checks the type of every control. When this control is a TextBox, DropDownList, Button or an ImageButton the control gets casted to a WebControl and the Enabled property gets set.