Tuesday, February 26, 2008

Preventing Web Caching in ASP.NET

We are working on a shopping cart application in ASP.NET. that needed to prevent web caching. The code is in VB.NET, since the best practice source we bought was VB.NET based.

With the proliferation of browsers, and the variety of ways that they interpret directives, a number of strategies have to be employed.

Caching can occur in any of the following locations:
  • Any – cache anywhere including client, server and proxy server.
  • Client – cache in client browser.
  • Downstream – any cacheable devices but not the original server that participates in the request.
  • Server – cache on the web server
  • None – no cache
(Please ignore the lack of indenting ... blogger kept losing my directives

Public Shared Sub NoCachePage(ByVal currentPage As System.Web.UI.Page)

' This will turn off the cache for the above locations

currentPage.Response.Cache.SetCacheability (Web.HttpCacheability.NoCache)
currentPage.Response.Cache.SetExpires (DateTime.Now().AddDays(-366))
currentPage.Response.Cache.SetMaxAge (
New TimeSpan(0))
currentPage.Response.Cache.AppendCacheExtension (
"must-revalidate, proxy-revalidate")

' This is to explicitly add to header to avoid being cached in the client browser, without the above code the page might still be cached on the server but just not in the client. For example cache is set to Server and the following codes are also added

Dim Expires As New Web.UI.HtmlControls.HtmlMeta()
Expires.Name =
Expires.Content =

Dim CacheControl As New Web.UI.HtmlControls.HtmlMeta()
CacheControl.Name =
CacheControl.Content =

Dim Pragma As New Web.UI.HtmlControls.HtmlMeta()
Pragma.Name =
Pragma.Content =

End Sub

Friday, February 22, 2008

Spawning a console application and tracking its Standard Output

Toby Cosham, our Accounting Guru, has the first tech oriented blog post to contribute, helping us achieve our milestone of at least a post a week. Thanks Toby.

Sometimes programs we write must interact with a console application that does not integrate easily into our framework. The application may be designed for use in a manual environment, but you need to automate it. Any errors produced may be displayed only on the screen via Standard Output.

This happened to me recently. My program was written using the .NET framework. It is pretty simple to run another program from the .NET framework. I used System.Diagnostics.Process to launch the other software (I’ll call it ABCD) using Process.Start, and waited for it to complete using Process.WaitForExit.

The purpose of ABCD is to send and receive data over the internet. It is a command driven program, with an interface similar to FTP. After testing its responses, it became apparent that it was unreliable. Not only could it return errors about failing to connect to its server, but also logon failure and timeouts. In addition, there were some more obscure, but regular, failures – corrupted stream and handshake failure. There was no way to predict these failures, but trying again immediately almost always worked.

The requirements for my program included executing ABCD many times each day, starting at 1am and finishing at 7pm. If it did not work, immediate action needed to be taken. At MaxSoft, we have a library that handles sending the SMS, so sending the message was not a problem. However, since the SMS was to our CIO, it was important to identify the problem and attempt to rectify it first.

ABCD does not return an error code. It does not log its results to a database, or a file. The only way it notifies its results is directly to the screen. In addition, when it downloads files as a batch, the batch can contain multiple files of the same name. The first file gets overwritten by the second file with the same name. This meant that I could not pipe the standard output of ABCD to a file and interpret it after it had executed – some files would have been lost by then.

The answer was to use some of the features of System.Diagnostics.Process. This class allows for the Standard Output (which normally is displayed on the screen) to be captured as it occurs. It also allows for Standard Error to be captured, and for Standard Input to be written to. I passed the commands to ABCD by writing to the StandardInput stream, allowing me to protect the user id and password.

I then set Process.EnableRaisingEvent to true and called Process.BeginOutputReadLine. This activates the OutputDataReceived event, which I set to call my OutputDataReceived function.

I set up an array of strings for the expected result. The output was the same all the time, except the list of files produced, which I added as a place-holder string to the expected result. Each time OutputDataReceived was called, I compared the text that had been added to StandardOutput to the next item in the expected results. If it matched, I removed that section from the expected results and exited the OutputDataReceived function. If it did not match, I recorded the error and exited the function. When Process.WaitForExit completes, this error information is checked to determine if the process has run correctly or not. The placeholder string is used to identify when the list of files is being processed. This is only removed from the expected result when the following expected result is received.

Having written this, I was getting all errors reported. I wanted to reduce the calls our CIO received early in the morning (So did he), so I processed the error message. If any of the three errors that could be retried occurred, I looped back to where ABCD was being set up and ran it again. Along with providing the maximum number of retries, this eliminated alerts being generated on transient errors. If any other error occurred, ABCD was not rerun, and the alert was sent straight away.

Issues that I had resolved include:

- calling a console application using System.Diagnostics.Process

Process p = new Process();
ProcessStartInfo si = new ProcessStartInfo(application);
p.StartInfo = si;
si.Arguments = arguments;
si.UseShellExecute = false;

- retrieving and interpreting text output to the screen

si.RedirectStandardOutput = true;
p.EnableRaisingEvents = true;
p.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceived);

timeouts and other retryable errors

void OutputDataReceived(object sender, DataReceivedEventArgs e)
if (e.Data == null)

// check e.Data for retryable errors and set flag indicating retry required

- preventing the console application for running forever by using WaitForExit with a time limit

if (!p.WaitForExit(Config.TimeoutSeconds * 1000))

Wednesday, February 13, 2008

Regular catch up meetings come full circle

In the IT department here at MaxSoft, we hold fortnightly catchups with the guys. Since there are currently ten guys involved in these regular catchups with me, I have one scheduled every day of the week. We cover three main points religiously:

  1. What have you done in the four hours a week we give you to develop your skills

  2. What are your priorities and work issues

  3. How are you going generally and what improvements can be made to your environment

We cover a lot of ground in these meetings. In a recent catch up, we covered the contrasts between other workplaces and the environment here. The discussion on other workplaces verged into toxic workplaces, and terrible management types.

I was reminded of a subject I had covered a few years ago, dragged out a book called “Mask of Sanity” by Hervey Cleckley. It is available as a free pdf download, and covers the pathological personality type. Get it from http://www.cassiopaea.org/cass/sanity_1.PdF

A summary covered at http://www.cassiopaea.com/cassiopaea/psychopath.htm describes this personality type as follows:

Imagine - if you can - not having a conscience, none at all, no feelings of guilt or remorse no matter what you do, no limiting sense of concern for the well-being of strangers, friends, or even family members. Imagine no struggles with shame, not a single one in your whole life, no matter what kind of selfish, lazy, harmful, or immoral action you had taken.

And pretend that the concept of responsibility is unknown to you, except as a burden others seem to accept without question, like gullible fools.

Now add to this strange fantasy the ability to conceal from other people that your psychological makeup is radically different from theirs. Since everyone simply assumes that conscience is universal among human beings, hiding the fact that you are conscience-free is nearly effortless.

You are not held back from any of your desires by guilt or shame, and you are never confronted by others for your cold-bloodedness. The ice water in your veins is so bizarre, so completely outside of their personal experience, that they seldom even guess at your condition.

Around 4%, or 1 in 25 people will have this personality defect. There are a lot of sociopaths in jail and just as many in senior management.

My original motivation for reading this tome was to try to fathom the behaviour of a colleague of mine while working in a large organisation. He was charming, fearless and ruthless, and his superiors loved him. He also seemed not to care an iota about anyone, nor about getting the job done. His actions included borrowing a subordinate's laptop to test a program he found on the web. The install process included disabling the corporate virus and malware protection suite and led to the first ever major outbreak of a virus at this company. When it was obvious that the forensics clearly pointed to his employee's laptop, he loudly and publicly led the charge to have him sacked, while privately telling the employee to sit tight. The employee was saved from dismissal by a divisional general manager who intervened. When the employee confided in me six months later, it was because his boss had neither thanked him nor apologised for his behaviour.

I'm sure most of you with a few years under the belt have had experiences with personality types you never, ever want to be involved with again. There are some that you'd especially go to great lengths to make sure that you never had to work for again.

What I am particularly interested in is how to use this feedback about the negatives of other workplaces into something that can be used positively.

The impact management, and especially the direct manager has on employees is massive. Any manager potentially can create an environment that is going to drive away not only your best and brightest, but your best and brightest in training. And you may never know about this until it is far too late.

If you care about care about getting great results for your business, the quality of the code your team produces, and the team itself, you need to provide an environment which not only stops your guys worrying about your reaction to situations, but also has them telling recruiters to stop calling for anything other than another dream job that pays twice as much.

Regular catch up sessions are a vital component to ensure that your guys are not only happy and productive, but also that you are not making them ticked off and distracted.

Some useful tips for these regular sessions:

  • Have a predictable agenda of open questions designed to open up conversation rather than confine it.

  • It is a two way street - your performance should be discussed as well.

  • Don't cancel these meetings too often – if they are run well, there's not many things that are more important.

  • Personalise the meeting to the needs of the employee. Take notes if you do not have a good memory.

Run well, these meetings should be able to nip potential problems in the bud, fine tune your department's priorities, improve your management style and also help you establish a quality relationship with the people you should value most in your company.

Even better, your annual or six monthly review process should be easy, painless and contain no big surprises.

By the way, we are currently looking to increase my regular catchup meeting workload by hiring more .NET engineers wanting to work in an environment that cares about employee development and producing great code.

If you are interested, e-mail me, Kent Bolton. I can be contacted via kbolton with an at sign here maxsoft.com.au. Please only apply if you are able to work on the gold coast in Australia, and have a serious passion for coding.

Friday, February 8, 2008

In interviews, test for the corner cases

This article deals with interviewing corner cases. It veers off the beaten path a little, and I'm keen to know if this is a good or bad thing.

We interviewed someone face to face today.

That little nugget of info is not so uncommon that I'm compelled to blog about it ... we currently hold about three or so face to face interviews a week.

The coder looks good on paper ... twelve years coding, the last three years hands on C# - and self rated at 7 through 9.5 out of 10 for technical skills.

Our first icebreaker exam question is designed to settle the candidate's nerves by being nice and simple. It's a property. “Tell us about it” I ask.

This guy proceeds to tell us in no uncertain terms that our three line code snippet was plain bad coding. I was intrigued, so I gave him the keyboard.

The keyboard I use for the interviews is a weird wireless Microsoft one. It has a super sized delete key that invades the space where the Insert key should be, and has the added bonus of weird key spacing. It's pretty horrible really, unless you are forewarned and expecting it, or have one just like it at home. I'm just starting to get used to it. It's taken me close to a year. The really great coders we interview never seem to have much trouble with it.

Well he starts fumbling away and out it comes – I recognise three different languages and some new form of pseudo code. There's not one identifiable C# keyword (admittedly there is a semicolon that is in the right place). It's a mashup of sorts. It's not Web 2.0. It's not the sort to get you hired as a senior coder. Well, certainly not for a C# role. Well, not _this_ C# role.

Terminating the interview within five minutes is unfortunately far from uncommon. Lots of coders with brilliant CVs bomb out on the warm up questions – questions even those cramming C# for dummies while sucking on Red Bull the night before should get right.

The reason for this is that lots of coders lie through their teeth on their CVs. There must be a reason – and I know that someone's been rewarding these time thieves with a job somewhere along the line.

For both your and the common good, you should never, ever interview candidates without the aid of a standardised exam that allows you to compare previous answers to gauge exactly where this candidate fits on the totem pole. This applies to every type of candidate I have helped to hire - accountants, office managers, junior network engineers etc. You Need An Exam.

This exam should be pitched for the corner cases. It needs to be interactive – rather than having them fill out the answers and then you marking it, you need to be there, listening and prompting them for more clarity. It should be as close to real world as possible.

The test results should be:

  • The really bad candidates should fall out immediately.

  • The OK ones should be guided swiftly though to the end; and

  • The really really seriously talented coders should make the exam so much fun you miss dinner with the kids.

The exam should be first cab off the rank - no time wasting chit chat or bonding before hand (you can do this if they are a good match) – my order of proceedings is offer freshly ground coffee, tea or iced water, remind them that they were warned about the tough exam, then hand it to them and provide instructions on how to navigate it.

This way they get to show us just how good they are. All the guys we have hired since I started at MaxSoft have gone through this exam, and _all_ of them loved it. For the right person, it's a blast ... a bunch of techie guys rabbiting on about code and objects and heaps and more code stuff. I learn a lot from these interviews, and am sometimes amazed at just how smart and quick and good some coders actually are.

I've gotten about three more pages on the cutting floor that I'm going to turn into more articles over the next few days. Here's some ideas I have:

  1. Why I created this exam, and how it has morphed

  2. My four step interview process

  3. Some bizarre personality types I have interviewed

Hopefully the guys will be submitting some interesting code samples ... CruiseControl, controlling batch driven software and Vista certification are all in the pipeline

Wednesday, February 6, 2008

First Post

This article was submitted by William, and is designed to give you an insight into our team and workplace.

The IT Team

First things first, “us”…

The Development and QA teams are from varied professional backgrounds (such as Mining, Finance Sector, Retail, Transport, and Gaming) as well as places of origin (QLD, VIC, NSW, UK, China and even exotic NZ). This “rich mix” has lead to good balance and experience coverage on design and support tasks.

MaxSoft encourage skill and knowledge development, so most of us are undertaking MSCE courses (partially during work hours and with paid for online courseware). Others are furthering education via University (ie Masters Degree).

We are a small group (under 20) most of us located in the one area – which allows for problems to be solved / discussed quickly and without the need of excessive emails! We do occasionally work offsite.

We all get along pretty well – except for the Games/LAN nights when we show no mercy :) These are every few months, and are additional to the regular company social activities.

The Environment

OK, the gear and stuff we use…

Typical Developer Kit is;

H/W: Core 2 Duo 3.0Ghz +, 2GB RAM, Dual 19” LCD Screens
OS: MS Server 2003 or XP (A few copies of Vista on test VMs)

Tools & Languages

MS-Visual Studio 2008 [C# and Web (Services, Forms)]
MS-Visual Studio 2005 [C# & VB.NET, ASP.NET]
MS-Visual Studio 2003 [C# & VB.NET, ASP.NET]
Some of us even have a copy of VB6 for legacy systems
FxCop for coding standards
WATiN for web testing


MS-SQLServer 2000 & 2005

Some of us have “natural keyboards” some view this as very un-natural.
Some of use wear head phones and play music whilst we work. The others throw things (usually rubber balls) to get peoples attention.

We are developing a new build and test server, running VMWare ESX, running CruiseControl.NET, MSBuild , nUnit, nCover, FxCop, memory profilers, WIX and other tools.

We take peer reviews very seriously (this is as close to pair programming we feel is necessary), and have a QA department which is part of IT.

The Systems

What we do….
• Payments web service channel (for a number of branded payment types – Rent, Strata Levies, Schools)
• Windows client based Strata Manager Office software
• Donation web service channel
• We write banking software for the banking services we provide

The Future

Where we are going….

New systems are being constructed now and some major ones just around the corner. Our life is not a static one.

We strive for generic approaches for extensibility.

The new framework platform we are targeting is in essence;

  • 2008 .Net C# 3.5 (including lots of method extenders)
  • nHibernate and nVelocity for the code gen and back end
  • Targets Microsoft SQL Server / PostgreSQL / MySQL database
  • Mostly Active Record with some domain concepts thrown in
  • Lots of custom libraries to speed up development and maintenance