ERROR: Cacographic Solecism Directive Encountered **
** Unreadable Error Message Found
I’m pretty picky about user interface with a lot of the projects I work on ranging from the user experience to the design and layout. Ever since I read Steve Krug’s, Don’t Make Me Think, I find myself spending a lot of time reading over the same content again and again trying to simplify them to their shortest possible length.
One section that has always been a focal point for me has been error messages or really any dialog that requires user interaction. However, I’m not just talking about the cryptic, developer designed error messages like ‘IOError Detected!’ or ‘Generic GDI+ Error’ (I especially hate that error).
No, the error messages I’m talking about are messages that don’t really help the user — or error messages that help the user, but too late into the message.
Here is an example from Netflix. It isn’t a bad message but I think that it could be improved.

The Anatomy Of An Error Message
Not all situations are the same but I try to write all of my error messages in the following order.
- What happened in a short sentence.
- Give the user options and solutions
- Explain in slightly more detail what happened but only if the problem may happen again or it helps them understand how to avoid the problem.
What Happened? Few Words Should Say It All — Or Don’t Bother!
I try to stay brief with everything… well, except blog posts, of course. If you’ve visited my latest project CustomWebmail.com then you’ll notice I try to keep everything to a sentence or two. I’ve had a lot of feedback that people like how short and to the point everything is.
Your error message should be the same – short and to the point. Don’t waste a lot of time explaining why it broke or telling them what happened in the background that caused the failure.
In some cases you don’t even need to present the problem as an error message especially if the resolution is simple. The Netflix message is a good example of this. The message feels a lot like an error – but should it? Or should it be presented that this message is the natural result of leaving the page idle?
User Options – Empower The User Quickly
Giving the user the control to fix the problem right away should immediately follow the title of the error – not an explanation of the problem. Include only as many options are really relevant.
I’d even go as far to say that even Yes and No buttons should have a description as well. Explain what the yes and no buttons will do — even if it seems obvious. A button that reads “Yes; Save my document to the server” is much clearer than simply a button that says “Yes” or “OK”.
The Netflix error says to reload the page — manually. Why? Chances are they already have a mouse nearby — why not simply say Click Here To Continue Your Movie! and handle reloading their page when they press the button?
They do offer a suggestion but they don’t offer to do it for you, which I think would improve this box a little more.
Explain The Problem: But Only If It Matters
I’m sure this part would be a point of contention to many people. Often we feel like we need to tell the user what is wrong but also why there was a problem. Clearly, each situation is different, but more often than not I think that the ‘why’ is irrelevant. Here are a few times I think explaining why is important.
- The user might make the same mistake again (ex. invalid e-mail addresses)
- The problem might make a user think your service is broken and you need to explain that it is either normal procedure or a problem from somewhere else.
- To answer why a response is required (ex. input form that wants information a user might not be comfortable in providing)
More or less, if the reason why doesn’t affect the user then you don’t need to share it. If your function SaveUserData() crashes and returns an ‘Unable to save to /Data/Profiles/Users.txt’ error then don’t tell your user. Simply saying ‘We’re sorry – We had a problem saving your information’ is more than enough information to explain why they need to do the same step twice.
My Version
Remember, I like to nitpick this kind of thing. I realize that error messages in my own programs could be improved as well. That said, here is a sample that I think would work better for visitors.

With this message, we are to the point faster and offer a solution to the problem immediately. I also dimmed the error message some and highlighted the actions that could be taken so the user would be drawn to it quickly. I’m sure this message could be improved upon even more but this seems like a good start.
How much time do you spend making your messages as short and as simple as possible?
** The author spends a lot of time reviewing content — but not his own blog — so if you see any typos then please be forgiving
Creating CustomWebmail.com – Part 1
CustomWebmail.com is a website that allows you to to create a custom login page for your Outlook Web Access by making changes to the colors, logo and layout of the page. This is a series of blog posts that discuss some of the more interesting parts of developing this project.
The Key Parts Of CustomWebmail.com
In order to develop CustomWebmail.com I had solve a few problems…
- What is the correct address to post logon attempts to?
- How can I be reasonably certain that the address is correct?
- How do I create their custom OWA page with the correct colors and logo?
- What is the best way to convert an theme image into an actual HTML web page?
- How can I package their content into a single .zip file?
For the next few weeks I’ll be going over all the steps I used to allow visitors to create custom Outlook Web Access pages with this site.
Determine The Correct Address
Now, this part is probably not close to perfect yet. As it turns out OWA isn’t standard across the board. I’m not just referring to OWA 2003 compared to OWA 2007 — but even matching versions can have different setups. With that said, the application still needs to come up with the correct postback URL to for the final rendered page.
Asking the visitor for the correct URL is probably not really a good idea. They might not understand where to look inside the form or what the address should look like. Instead, the application simply asks them for the address of the Outlook Web Access login page and then uses a series of HTTP calls to determine the rest.
string path = "http://webmail.example.com/exchange";
HttpWebRequest request = HttpWebRequest.Create(path) as HttpWebRequest;
request.UserAgent = USER_AGENT;
request.CookieContainer = result._Cookie;
//get the response from the requester
response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
content = reader.ReadToEnd();
}
//use content to determine form related information
//...
This section of code tells us a few things…
- Did a server respond to our request?
- Were we redirected to a different URL?
- Which level of security was used – http or https
- If the server doesn’t respond was it really because nothing was there?
- Does the content contain anything that looks like an Outlook Web Access page?
- Are we sure that this address will accept our login attempts?
Yikes! Unfortunately those are all real problems that need to be solved in the code — and anything unsuccessful needs to be reported back to the user (or repaired on its own). I’ll skip over the first three since they are fairly easy to determine.
Exception With A Responding Server?
I’ve found that with the HttpWebRequest sometimes you get an exception even if the server is found because the certificate at the site isn’t valid. It throws you off quite a bit especially if you’re expecting a response and your code simply crashes.
As it turns out it isn’t hard to handle invalid certificates.
//Ignore bad certificates
// ** Use at your own risk **
ServicePointManager.ServerCertificateValidationCallback = (obj, cert, chain, ssl) => {
return true;
};
In my case I’m not too worried if the server’s certificate is valid – I just want to know if it is responding to my requests. By adding in this line of code I can ignore anything invalid and move forward.
Just What Is This Page Anyways?
There are a few arguments you need to use when posting back to an Outlook Web Access login page. We wouldn’t want to accidentally create a login page if someone entered ‘google.com’ instead. By using a couple Regular Expressions we can check to see if the form looks like an Outlook Web Access page.
Here are some of the fields you can check for…
- An input named username
- An input named password
- An hidden input named destination
- An form action to something containing owaauth.dll
There are more fields you can use but these tend to be a fairly sufficient indicator if we’re looking at an Outlook Web Access form.
Testing The Login
At this point we’re fairly confident that the server we are looking at is an OWA login page but there is one more test we can try. In the final test we perform a fake login to the page to see if we get a password failed error response.
//test the target of the form that was found
HttpWebRequest request = WebRequest.Create(formTarget) as HttpWebRequest;
//create the standard postback information
string post = string.Format(
"username={0}&password={0}&forcedownlevel=0&trusted=0&flags=0&destination={1}&isUtf8=1",
DateTime.Now.Ticks,
HttpUtility.UrlEncode(this.Destination)
);
//prepare the request
request.MaximumAutomaticRedirections = 10;
request.UserAgent = USER_AGENT;
request.Method = "POST";
request.Timeout = 15000;
//and add the content
using (StreamWriter writer = new StreamWriter(request.GetRequestStream())) {
writer.Write(post);
}
//get the login attempt result
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
response = request.GetResponse() as HttpWebResponse;
//check if a reason code was included
return Regex.IsMatch(response.ResponseUri.Query, @"(&|\?)?reason=\d", RegexOptions.IgnoreCase);
It is possible that we just happened to come across a random server that returns a response code but given all the other tests we can be fairly confident in the address we’re testing.
As a final option we present the user with a test login box that they can try to do a personal verification that the address works.
Introducing CustomWebmail.com
I like blogging but the past few weeks (maybe months?) my posts have gotten a little sparse — but for good reason! I’ve been working hard on completing another project and this weekend was the launch date!
What Is CustomWebmail.com?
I do a lot of contract work ranging from programming applications to fixing other in-house developed applications. One job that always gets a lot of interest is customizing a corporate Outlook Web Access login page. I’ve done several of these for a variety of companies.
The idea behind the website was to move the entire customization process online and then present the user with a nice neat .zip file of the resources they would need to install on their webmail server.

How It Was Made
The site uses ASP.NET MVC, C# and jQuery — I couldn’t find a use for my jLinq project, unfortunately
. The site does a lot of interesting things in the code like checking remote sites via HttpWebRequest or creating HTML and image slices using the System.Drawing classes. Over the next few weeks I’ll go over some of the more interesting parts of how the site works.
For now, if you have any Server Admin buddies that might be interested, please tell them about http://www.CustomWebmail.com.
Render Partial — But With Arguments!
One thing that I haven’t really liked about MVC was using RenderPartial instead of an actual UserControl. Its not that you can’t use them but that there is a disconnect between the control state and the render phase which makes it pretty much impossible to really work with them inline.
I say ‘pretty much’ because I’ve done a lot of work to let people use WebControls inline with MVC code.
Using the existing RenderPartial requires that you pass in the name of the UserControl that you want to render. You can also provide an object argument that is passed in as the ‘Model’ for the partial view. The UserControl can access the passed in object via the ‘Model’ property — even cast it into the correct type directly.
Personally, I use a lot of Models in my projects now. I used to suggest that you pass around objects using a wrapper for anonymous types but I’ve found that if you plan to move it from a Controller to a View or from a View to a UserControl then you ought to define a class.
Using RenderPartial Without Really Using It
So instead of calling RenderPartial directly, what about using the Model that we have in place to make the call for us. Not only that, we can even define our class to accept arguments directly. Here is an example of a simple dialog box…
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace MvcTest.Models {
//simple dialog box example
public class DialogBox {
//rendering the dialog box
public static void Render(ViewPage insideView, string title, string message) {
insideView.Html.RenderPartial(
"DialogBox",
new DialogBox() {
Title = title,
Message = message
});
}
//Properties
public string Title { get; set; }
public string Message { get; set; }
}
}
Then we could simply use our code inline by calling the DialogBox.Render instead of the RenderPartial method.
<% DialogBox.Render(this, "My Title", "This is the message to display."); %>
You could also use an approach like this to make creating UserControl templates easier.
using System;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace MvcTest.Models {
//simple product list example
public class ProductListing {
//rendering the list of controls
public static void Render(ViewPage insideView, List<Product>, Action<Product> renderRow) {
insideView.Html.RenderPartial(
"ProductListing",
new DialogBox() {
AllProducts = products,
RenderRow = renderRow
});
}
//Properties
public List<Product> AllProducts { get; set; }
public Action<Product> RenderRow { get; set; }
}
}
And then you could call your method inline and provide the template action.
[View.aspx]
<!-- snip -->
<% DialogBox.Render(
this,
products,
(item) => { %><li><% =item.Name %></li><% }
); %>
<!-- snip -->
[UserControl.ascx]
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MvcTest.Models.ProductListing>" %>
<h3>Featured Products</h3>
<ul>
<%
foreach (Product item in this.Model.AllProducts) {
this.Model.RenderRow(item);
}
%>
</ul>
The above example is probably over simplified but you probably get the idea. This may not be a big gain, but if you plan to use the same UserControl often, then this might help simplify the call.
Spelling It Out With Booleans
Code complexity has been a big issue for me lately. I’ve been realizing that the quality of my code has degraded over the years to the point that I’m finding I cram large chunks of code into a vaguely named method like Load() or Render(). It wasn’t until I got an assistant and I likened programming to ‘painting by number’ that I realized that I wasn’t following my own instructions anymore.
It wasn’t that I was intentionally writing complex code but rather that a large complex function wasn’t hard to read anymore — my definition of complexity has changed.
The last time that I discussed code complexity I explained that writing short, clear methods was an ideal way to decrease code complexity. This post continues the discussion by looking at using booleans to improve the readability of code.
Clarity With Booleans
Maybe you’ve seen a snippet of code like this before…
if (value % 2 == 0) {
//do something
}
else {
//do something else
}
Most programmers are going to immediately recognize what this code is going to do — but imagine for a second that you don’t know what that code does. How is a less seasoned programmer going to have any clue what just happened there? Try Googling ‘value % 2 == 0′? I don’t think that is going to work out so well.
This is a good example where a boolean can be used to create clarity in a program. A boolean is used to determine the flow of a program — so why not use well named booleans to further clarify your intent?
bool isEvenNumber = (value % 2 == 0);
if (isEvenNumber) {
//do something
}
else {
//do something else
}
This is a simple example but it applies everywhere. What stops you from spelling it out with a boolean?
Describe Intent Without A Comment
MVC is a good example of where well named booleans can improve the readability of code. How much harder is the first snippet to read compared to the second.
Logic Performed Inline
<div class="<% if (allItems.IndexOf(entry) % 2 == 0) { %>alt-item %<% } %><% if (entry.DatePosted.Date < DateTime.Now.Date.AddDays(-7)) { %>old-post<% } %>" >
<div class="subject" ><% =entry.Subject %></div>
<% if (string.IsNullOrEmpty((entry.Location ?? string.Empty).Trim())) { %><div class="location" ><% =entry.Location %><% } %>
<% if (string.IsNullOrEmpty((entry.Description ?? string.Empty).Trim())) { %><div class="desc" ><% =entry.Description%><% } %>
</div>
Logic Performed In Advance
<%
bool isEvenItem = (allItems.IndexOf(entry) % 2 == 0);
bool olderEntry = (entry.DatePosted.Date < DateTime.Now.Date.AddDays(-7));
bool hasLocation = (string.IsNullOrEmpty((entry.Location ?? string.Empty).Trim()));
bool hasDescription = (string.IsNullOrEmpty((entry.Description ?? string.Empty).Trim()));
%>
<div class="<% if (isEvenItem) { %>alt-item %<% } %><% if (olderEntry) { %>old-post<% } %>" >
<div class="subject" ><% =entry.Subject %></div>
<% if (hasLocation) { %><div class="location" ><% =entry.Location %><% } %>
<% if (hasDescription) { %><div class="desc" ><% =entry.Description%><% } %>
</div>
Snippet one is much shorter than snippet two — but does that really make it better? Or less complex?
You could argue that the logic shouldn’t be inline with MVC to begin with and you’d be correct. Instead those same comparisons would be well named boolean properties attached to the the model being used — which is exactly what I’m suggesting here.
It doesn’t matter where they are but using well-named booleans can improve and clarify the flow of logic in your application.
MonoDevelop – Pure Awesome!
I’ve always been envious of Java developers since they could essentially write their code and then run it on any device. It might not be a perfect translation each time, but its still much better than what a pure Windows dev could put together.
I recently started doing some iPhone development and decided to investigate MonoTouch. I downloaded the a copy of MonoDevelop (which is still in beta at this time) and installed it. After starting up the application I was shocked to see what came up…
Uh… what? Wow! Is this for real? This really looks pretty nice!
Not What You’d Expect
When you first mess with the IDE you’ll be pleased to see it works just like you’d hope. Intellisense is quick and accurate; Syntax highlighting works as you would expect; Believe me when I say, it is just that impressive.
But having a pretty IDE is nice but it doesn’t mean anything if the language doesn’t work the way you need it to. Honestly, I figured it had to be some sort of watered-down version of the same .NET C# language that I work with every day. The first thing I did was hack out something that was certain to fail… but…
Incredible! Granted this isn’t that hard of code, who would have thought so much was already available!
And that isn’t all – You have LINQ support, Generics… heck, even ASP.NET MVC is already packed in here!!
Not only that, but check out this “little” dialog. I’m sure it doesn’t mean much…
If I’m reading this correctly, we can import existing .NET assemblies – How awesome would that be! (but I’m just guessing here… I’ll test it later…)
See It To Believe It
Mono and MonoDevelop are going to open up a lot of existing C#/Windows devs to an entirely new world. Don’t just take my word for it though — try it out for yourself. It doesn’t take a lot of effort, download a copy of VirtualBox and setup a virtual instance of another OS and prepare to be impressed.
Great job Mono Team! I think the benefits of .NET cross-platform development are yet to be realized!
MVC Post Round-Up
I thought I’d bring back a few of my previous ASP.NET MVC posts just in case they were missed before.
Include Stylesheets and Scripts To Your Header With MVC
A while back I wanted to include some stylesheets in my header of a MVC View, but I wanted to do it from a WebControl. Since you’re using inline code the standard Page properties like “header” aren’t going to do you much good (since you’re already in the render event). Fortunately, with a little magic with the HttpContext.Current.Response.Filter stream, you can make all the changes you need before the content is sent to the user.
Using WebControls With Inline MVC
Just for fun I wanted to see if it was possible to actually create WebControls that worked inline with MVC Views. It took a little bit of work to do (it actually ended up spanning 4 different posts) but it finally came together fairly well.
This series was actually inspired at the idea of just rendering controls inline, without postbacks.
- Part 1 – The ViewState Problems
- Part 2 – Simple Postbacks!
- Part 3 – Coming together! Source Code
- Part 4 – How It Works… sorta…
Combining MVC with Existing Web Services
I like the idea behind WebServices, but the hassle of creating SOAP envelopes and modifying headers makes them difficult to use in places other than .NET applications. Being able to create a MVC Controller that automatically maps to an existing WebService would make it easier to use the same functionality, but all from a standard HTTP call.
Anonymous Types (Sorta MVC related…)
If you’ve worked with Anonymous Types in MVC then you’ve probably noticed that you can’t just pass them into your view and expect them to be available. Personally, recommend creating a unique class for anything that you’re passing into a view – but if you’re looking for something that you can use in a hurry, then this Anonymous Type wrapper class might come in handy. Just pass in an anonymous type and the class does the rest!
You can change values, assign new methods — basically you have a little bit of dynamic programming goodness all wrapped into a single .NET class!
Outlook Web Access via iPhone
You may have seen my post a little while back about how I was starting to do some iPhone development for my job. For the most part the app is nothing more than a nice pretty front end to a handful of Web Services (hint: last blog post was along the same lines)
In any case, I’d rather my first attempt at iPhone development be a throw away project since I’m going to probably going to have to start over several times.
Learning Through Development
Whenever I offer up advice to a new programmer on what is the best way to learn programming I always say – “write a program that does something you want — you’ll learn a lot along the way and have motivation to finish it.”. Learning Objective-C was no exception for me.
Even though we use Exchange for our e-mail server at work, we don’t have the “Active Sync” enabled so you can’t link up with the iPhone through the built in e-mail application. So, instead, I decided to go a different route — use the existing Outlook Web Access and parse the HTML.
So with a couple of nice Regular Expressions and some HTTP calls we have a nice clean display of all the e-mails in my mailbox. Yep, that’s right — screen scraping via HTML… a little cheesy, but not bad since it works even if Exchange isn’t configured to allow it!
This was a perfect example of writing an application that met my need and allowed me to learn a new language at the same time… of course I’m not suggesting that I’m an Objective C expert or anything but at least now I can ditch my BlackBerry!
Hey, Who Puked On My Screen… Oh Wait, That’s Objective C
I’m definitely a spoiled programmer. Using .NET and C#/VB has definitely shielded me from some ugly languages out there. Objective-C is the kind of stuff that makes babies cry.
Developing iPhone is WAY different that anything that you have ever done in .NET. You’re adding all sorts of weird things like IBOutlet and IBAction so you can link them around all over the place — it is definitely a new experience. I’m going to have to write a ‘C# Developers Guide To iPhone Development’ to maybe save some other poor guy a lot of grief.
Still a .NET Guy
Getting into new languages and technologies on different platforms is always a good idea. You gain added perspective while increasing your skill sets (not to mention you look better on paper for your next job). Even if you don’t want to buy a Mac and play with the iPhone you can always tinker with a myriad of other languages on any number of free operating systems — Go do it!!
Don’t think that I’m converting – If anything using a Mac this much has solidified why I’m still die-hard Windows/ASP.NET/PC…
…But then again… MonoDevelop for Mac is looking kinda slick…
Combining WebServices with MVC
I always liked the concept behind WebServices. Having a single place to store a bunch of complex but commonly used functions is a great way to decrease complexity of other programs that all sit on the same network. If you’re like me and tend to do a lot of intranet applications, a web service can prevent a lot of duplicate code.
My only real problem with WebServices was having to use SOAP. Adding a Web Reference to a project wasn’t that big of a deal but if you ever wanted to just call a function real quick, say from a script file (yes, I do VBScript occasionally… ick) then it isn’t quite as I’d prefer. You end up spending more time making sure your XML is well formed and less time on the logic inside your quick script.
MVC helps get around that problem by allowing you to perform normal HTTP calls and plug all your arguments into the query string or the body of the request – something much easier to do. The problem, however, is that you end up losing the convenience of using a WebService with other applications.
A Simple Solution
The idea here is to create a controller that acts as a wrapper to a WebService. By doing this we can override a few methods on our Controller that use reflection to invoke the matching method on the WebService. Also, because the Controller is still a unique class, we can still attach any number of Actions to it as we normally would. Below is some code that I wrote the other day. It isn’t battle tested so if you use it be sure to verify it does everything that you need it to do.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Mvc;
using System.Reflection;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.IO;
namespace Interface.Controllers {
/// <summary>
/// Abstract wrapper that handles calling WebService methods on behalf of a controller
/// </summary
public abstract class WebServiceControllerWrapper<T> : Controller where T : WebService {
#region Constructors
/// <summary>
/// Creates a new Controller Wrapper for a WebService
/// </summary>
public WebServiceControllerWrapper() {
this.Service = Activator.CreateInstance<T>();
}
#endregion
#region Properties
//The service that is being used for this call
private T Service { get; set; }
#endregion
#region Overriding Methods
//finds the correct method for the WebService method
protected override void HandleUnknownAction(string actionName) {
//find if the method exists
MethodInfo method = this.Service
.GetType()
.GetMethods()
.Where(found =>
found.IsPublic &&
found.Name.Equals(actionName, StringComparison.OrdinalIgnoreCase) &&
found.GetCustomAttributes(typeof(WebMethodAttribute), true).Count() > 0
)
.FirstOrDefault();
//if no method was found, just give up
if (method == null) { return; }
//check if all the arguments were found
List<object> arguments = new List<object>();
ParameterInfo[] parameters = method.GetParameters();
foreach (ParameterInfo param in parameters) {
//check if this argument was found
object arg = this.ValueProvider[param.Name].ConvertTo(param.ParameterType);
arguments.Add(arg);
}
//with the arguments try and call the result
object result = method.Invoke(this.Service, arguments.ToArray());
//if there is a return value, serialize it and write it
this.Response.ContentType = "text/xml";
if (method.ReturnType != null) {
//if this is an XElement of some kind, just use it as is
if (result is XObject) {
//write the string
using (StreamWriter writer = new StreamWriter(this.Response.OutputStream)) {
writer.Write(result.ToString());
}
}
else {
//try and serialize it
XmlSerializer serialize = new XmlSerializer(result.GetType());
serialize.Serialize(this.Response.OutputStream, result);
}
}
}
#endregion
}
}
The idea here is to inherit this class instead of the standard Controller class and provide the name of the WebService we want to wrap around as our Generic argument. For example…
//that's about it - actions are mapped automatically to the correct method on the webservice
public class AccountController : WebServiceControllerWrapper<AccountWebService> { }
By doing this, when our controller receives an Action, is checks the WebService instance for the same method and then tries to call the method with the arguments it finds as part of the request!
And that’s it! A quick and simple way to map incoming actions to a matching method on a Web Service!
The Return Type
I’m not sure the best way to handle the return type at this time. It seems to me that the XmlSerializer should be sufficient for object with the exception of Xml which should probably just be written out as a string. If you have a suggestion on a better way to respond to incoming requests, please let me know.
Remember: This is just some quick and dirty code – This needs some more polish and exception handling before I’d use it in a real project, but at least it might help you get going in the right direction.
Slightly Easier Recursive Functions
I’ve joked before that recursive functions were the kind that make you “curse over and over and over and over…”. Granted, they aren’t the most difficult thing to do in programming, they can tend to require a little more focus to write correctly.
So when you work with a recursive function you normally need to create some sort of safety counter to prevent an infinite loop. If not you end up passing around your counter by reference which can be a bit confusing to developers in itself.
Not only that, it also tends to hurt the “black box” approach to class design. Even if the method is private you still need to prepare a safety counter in advance before you can call the method — a function that has a order dependency, which isn’t a good thing.
Lambda To The Rescue
I love working with lambdas – I think that I cried a tear of joy the day I realized they could be passed as an argument (actually, I didn’t… that would be weird).
So what if we created a single lambda within our functions that would perform all of the recursive logic inline?
public void ScanElements(XElement xml) {
//create a safety counter
int safety = 0;
//declare the scan action as null at first
//since we can't call it recursively inside
//the method unless it is declared first
Action<XElement> scan = null;
//assign the actual work to do
scan = (node) => {
//increment the safety
if (safety++ >= 100) { return; }
//do the actual work here
Console.WriteLine(node.Name);
//and then recursively call the scan method again
foreach (XElement element in node.Elements()) {
scan(element);
}
//reverse the safety
safety--;
};
//now, actually start the recursive function here
scan(xml);
}
Now, that isn’t too bad. We have all of our logic encapsulated into a single method that doesn’t require any setup before it is used. It might be a little odd to a developer that hasn’t used lambdas much, but a comment explaining what is going on should be enough to get them onto the right track.
Maybe this is a terrible idea – I’m not really sure but it does decrease complexity and improve encapsulation — even if it is with a single private method.
Using the .Descendants() method as part of the XElement/XDocument classes would be much wiser here – this code is just an example of performing a recursive method.



