Umbrella Theory

Umbrella

Posted by A is for Angie

My wife and I have started to use a term we’ve developed called “Umbrella Theory.” It’s almost a synonym of “Reverse Jinx,” but there’s more to it than that.

 

The Reverse Jinx

By my definition, to jinx means to “foredoom to failure or misfortune by mentioning the possibility of an unlikely catastrophe.” A simple example would be saying “we are on target to reach our destination on time unless we meet stopped traffic at 2 in the morning.” If you believe in jinxes, you believe that mentioning that statement ensures you will “meet stopped traffic at 2 in the morning.” It follows that superstitious folks sometimes strategically mention the opposite outcome in hopes to influence an unlikely event in their favor. Stating publicly “the Miami Heat are a lock to win their 24th consecutive game tonight” is a reverse jinx if the orator also bets against the Miami Heat. If reverse jinxes worked, I would probably walk out my front door stating “It’s going to rain today,” and I would get to enjoy dry weather for all time.

 

The Umbrella Theory

“Umbrella Theory” has a special meaning in the parlance of our household. It stems from the experience that it seems like it never rains when we’ve gone through the trouble to bring an umbrella with us.

Let me walk you through a sample dialog:

Me: Is it supposed to rain today when we’re at the game?

My Wife: I heard it’s a possibility.

Me: Should I take an umbrella.

My Wife: “Umbrella Theory.” Just take it.

 

What inevitably follows is I take the umbrella with me and the weather stays clear. I simply have to endure the small burden of carrying the umbrella to be prepared, to ensure the negative event I’m preparing for doesn’t even happen.

It turns out I’m not the first to think of this.

 

What We Have Learned

The Umbrella Theory is admittedly silly. Still, it can be a useful guide in my family’s decision making process. When worrying about what to pack or how to prepare for something, the theory reminds us to prepare for the “Worst” if the preparations are relatively easy. Also, it is important to decide quickly. There is no reason to deliberate with the Umbrella Theory. Time spent determining whether preparation is necessary can just be spent on the actual preparations.

I hope this terminology catches on in your household. May you carry an umbrella with you always!

 

This Guy’s a Competent Communicator

Memorizing an Entire Speech is Difficult

In December, I completed my 10th and final Toastmasters Speech on the path to fulfilling my Competent Communicator certification.

The intention of the speech was to Inspire with the length being between 8 and 10 minutes.

On one hand, I feel I’ve learned a great deal from presenting 10 speeches at my Toastmasters Club. I’ve become much more confident and have a better feeling for what types of stories work when writing my speeches. On the other hand, I still haven’t mastered the ability to speak, and say everything I want, without notes. This was evident in the below speech. 8-10 minutes is longer than any of the others, so my attempts to memorize the entire thing left me pausing to search for the next line far too often. I am sure I can overcome this struggle with more practice.

With the certification out of the way, I can now relax a bit and have some more fun with my future speeches. I’ve got a couple of clever ideas I can play around with. Stay tuned to see them.

2013 New Year’s Resolutions and a Little Friend

Pregnant Women Celebrating ChristmasAs December nears, it’s time to brainstorm my New Year’s resolutions for 2013. The Stuller family is expecting its first baby in that time, so it’s entirely possible that any goal I set for myself will immediately seem implausible, thwarted by a new dependent and many personal misconceptions about the transition to parenthood. Still, naming my goals will be helpful, even if only the most important bubble up to the surface over the next year.

 

Certifications

In Were my Microsoft Certification Exams Worth it I detailed my experience with these types of certifications. My conclusion has been upheld so far, that the certifications themselves do not provide much value once a certain level of experience is obtained. Therefore, I’ve fully abandoned the idea of updating or getting new ones.

“Any sort of certification by a tool vendor is worthless. Any certification created by a methodology proponent is also worthless.” – David Starr on Herding Code episode 150

Despite the quote above, I’ve decided to make Scrum Certification a goal for 2013. I feel I have a good grasp of iterative project management processes but I could benefit from structured training about a specific, standard methodology. I understand that the certification itself is not the end goal, but it is a nice motivation as a milestone of my learning.

“If you go for certifications, remember your goal is not simply to put more letters after your name but to maximize the value of the educational experience. Winning the game requires that you not only keep your eye on the ball but also anticipate what the next pitch will be. Historical evidence suggests that the average lifespan of any system is approximately 18 months, so the planning process for how you’re going to replace what you just built starts pretty much the moment you finish building it. Planning is a lot more effective when you know what you’re talking about. Being informed on emerging trends is a fundamental job responsibility, something in our business that needs to be done daily to keep up.” – 10 Essential Competencies for IT Pros by Jeff Relkin

 

What am I going to do instead?

Yesterday I read Paul Graham’s most recent post, How to Get Startup Ideas. This blog post really cut to the core of me, as it described the best ways to identify startup ideas. While I sometimes come up with ideas for products, they don’t occur to me as frequently as I’d like. Paul articulated what type of people have the most success, namely those who “live in the future and build what seems interesting.” So that’s what I’m going to strive to do. Throughout my career, I’ve done a pretty good job of solidifying certain skills, such as specific technologies (SQL Server, C#, jQuery) or communication (writing and public speaking). However, I’ve been hesitant to jump into new, trending technologies. For a long time, I considered it beneficial to isolate myself from fad technologies, figuring I can save time that way. In 2013, I’m going to try to both live in the future and build what’s interesting. Maybe that means working a little on a mobile app or maybe HTML 5. I don’t want to constrain my options by listing any technologies before the year even starts. If something seems cool, I’m going to come up with an excuse to build something with it.

 

Public Speaking

I’m scheduled to wrap up my Toastmasters Competent Communicator certification by the end of this year (more on this in a later post). In 2013, I’d like to leverage the practice I’ve had toward some sort of speaking arrangement that advances my career.

 

Personal Life

As usual, I don’t just make goals for my career. There are also things I strive for in my personal life. Among those, I’d like to complete 1 big home improvement project (convert our half bathroom to a full or move my home office), get back in shape (how about a half-marathon), get involved (with my alma mater or our neighborhood).

 

The Blog

What should I do with this blog? This is post 45, which means I’ve devoted over 40,000 words to it. My site visitors are steadily increasing and they are even stable when I take an extended break. However, when I started 3 years ago I thought I would have had more traction by now. I enjoy having a forum with which to express myself but a) I’m running out of content ideas and b) I’m losing motivation based on the slow traffic growth.

Traditionally, I tend to bounce back and forth between technical articles and more generic lessons based on personal stories. Which category speaks most to you? I’ve said everything I need to say from a self-expression standpoint, so when I continue to blog, I want to ensure I’m providing something useful for my readers.

 

Bring in the New Year

Clearly, many of my ideas are half-baked. That’s partly because I still have a month to decide on New Year’s resolutions and partly because I have no idea what to expect of life with a child. Still, this post is important as a record of my mindset at this critical milestone in my life. It’s also an open invitation for discussion. What other goals or modern technologies should I be considering? How will a newborn affect my personal goals over the year? What type of content should I be producing?

Thanks for your time. You’ll be hearing from me again soon.

SWOGC: How We Built a Web Portal in under 48 Hours

Southwest Ohio Give CampThis past weekend I volunteered my time to the Southwest Ohio Give Camp for the 3rd consecutive year. All in all, it’s a great event, a local chapter of GiveCamp.org, where regional software developers, designers, and technologists gather together in teams to create working solutions for charities. In the past, I’ve merely volunteered my time and expertise, but this year I undertook a higher challenge, leading my own team. In this post, I discuss my plan for building an entire web portal in less than 48 hours and the lessons learned.

 

Leading a GiveCamp Team – The Plan

I had compiled 8 tips for myself through observation in past years. Going into the weekend, these were my keys to success:

Before the Weekend

  • Prepare with the charity representative to obtain the majority of requirements
  • Present the charity with a “Wish List”, what we need the charity to provide (e.g. logins or files) to be successful
  • Begin visual design collaboration and discussing philosophies
  • Decide on a CMS, such as WordPress or Umbraco

During the Weekend

  • Be pragmatic and cognizant of the critical path!
  • As leader, make sure there are no tasks during the weekend that only I can do
  • Stay clean and flexible
  • Create a project plan first

 

Putting it all together – The Execution

Knowing I would be leading my own team, I recruited 2 .NET developers to help over the weekend. In addition, the event organizers assigned me 2 more developers and a designer. Our charity’s representative was also there to help for almost the entire time.

From Friday evening to Sunday afternoon, our team of technologists contributed about 120 hours to the project. We implemented an internal employee portal for the charity made to match the style of the existing website as much as possible. I would say it was generally a success.

 

Lessons Learned – a Retrospective

“Is that it? That’s all you’re going to say about how the weekend went?”

Well, the details of the project weren’t that interesting. But now that you know what happened, I can remark on what I found to be most important about our strategy and implementation.

Getting Started was Difficult

As you might imagine, assembling a team of mostly strangers, who know very little about the task at hand, can present a specific set of problems. Namely, everyone struggles to dive into a task because of a lack of knowledge about the overall requirements, plan, and others’ skill sets while pitted against the aggressive time constraint.

I think this is somewhat unavoidable. I did a good job of following my own advice, numbers 4 and 8 from above. I also had a list of known tasks pre-written on post-it notes that I used as discussion points to explain the scope of the project. I think having had some of the bigger decisions made going into the weekend helped the team to focus on delivering value to the charity. However, the team didn’t seem to naturally mesh and become fully engaged until Saturday afternoon.

How could I have changed my approach to reach that point earlier? I could have gone further with my research for the weekend making sure that any technical roadblocks were overcome before we started. This became most obvious in relation to my choice of CMS. We were using Joomla!, the CMS that the charity already had for their existing website. Personally, I did not know enough about this CMS to get started in a reasonable timeframe. I was dependent on team members to get our site up and running and the members who did not know Joomla! did not have much to do. Looking back, I would either choose a CMS that I was already more comfortable with or make sure that I knew how to get started with what I chose. Alas, I realized I got lucky with my team member assignments by acquiring some Joomla! knowledge along with them.

Iteration is Awesome

Having the luxury of a charity representative throughout the weekend, we leveraged a tight feedback loop to ensure we delivered a valuable solution. In fact, around noon on Saturday, we all realized that a significant portion of the planned tasks would only be of marginal benefit. Because we adhered to tip number 7 above, we were able to have an ad hoc discussion with the charity about what would provide the most value. As a result, we scrapped many of the broad functionality on our project plan and replaced it with one deeply functional requirement. Had we not had an iterative approach we would not have been able to fulfill the charity’s actual needs.

Get a Designer

Every year, the most in-demand skill at these GiveCamps has been design. There are usually not enough designers for every team and this year was no different. We were lucky to get assigned one (who also was fairly knowledgeable in Joomla!). Having a designer on the team is important because there is no easier way to feel like your solution is worthless than to have it look subpar. This is especially true at a GiveCamp weekend, when all the teams present their results on Sunday and give you benchmarks to compare against. On a time constraint and non-existent budget, I don’t know many developers who could make a user-interface that meets the new standards of the web. Even though our charity was not looking for a “fresh” design on their internal portal, it was nice to have someone who could troubleshoot display issues as we put it together.

 

Would I Do it again?

In a word, absolutely. While I’ve found that the solutions created for these charities over the past 3 years have not been the most interesting technically, the delight and value we are able to provide for non-profit organizations is quite fulfilling. Sure, the weekend comes with a certain level of anxiety. At one point on Saturday, the Web Host for the charity’s site (and all our work in progress) went down temporarily rendering our team useless. Still, it is a great way to meet other local developers who do not necessarily work on the same platform in their day jobs. Leading a team of volunteers who just want to contribute their skills in the most effective way possible provides exactly the right amount of eustress, and I’d recommend it to anyone.

Lessons Learned Negotiating for my First Car

In my early adulthood, I hated negotiating. The process seemed dirty, one which often felt like it required dishonesty. I remember my one attempt to haggle for a $25 t-shirt at a market in the Caribbean when I was 17. My strategy: opening my wallet and saying I only had $5. Somehow the merchant saw through this ruse. I ended up paying full price with the money from my other pocket.

Negotiating down the price of something is uncomfortable for many people:

  • It creates confrontation
  • Logically, items should be marked with a price that everyone pays
  • Even after coming to an agreement, there’s always a sense of wonder if the price could have gone even lower
  • “Professional” negotiators often exaggerate with guilt trips such as “I’ve got kids to feed”

    In Business As in Life, You Don’t Get What You Deserve, You Get What You Negotiate

Immediately after getting my first job offer soon after college, I went with my mom to the local car dealership. She was the negotiator in the family who drove the hardest bargain. I bought a car that Saturday from the first dealership I visited because I needed one for Monday. I went in expecting my mom to work her magic, but I sat and watched while the only additional value we extracted was an extra year of oil changes. Over time, I realized that I basically paid full price for something I didn’t have to, and I became determined to reduce my ignorance of negotiation.

An important concept to understand about negotiation is optimal pricing. Essentially, this means that the dealership wants to charge as much as any individual customer is willing to pay. The price is set to an arbitrarily high amount and each customer negotiates it down to an amount he or she is willing to pay. The dealership would not sell a car below what makes a profit. The salesman’s job is to make you feel like that baseline price is higher than it actually is. Does that make you feel more comfortable about negotiating? The additional money being paid above the baseline is going straight to profit!

The same applies to other scenarios, such as at a street market or negotiating salary. Obviously, there are many additional economic factors to consider, of which I know only a little. However, knowledge of this simple concept can ease discomfort about the negotiating environment.

Reaching the end of a job interview, the human resources person asked a young applicant fresh out of business school, “And what starting salary are you looking for?”

The applicant said, “In the neighborhood of $125,000 a year, depending on the benefits package.”

The interviewer said, “Well, what would you say to a package of five weeks’ vacation, 14 paid holidays, full medical and dental, company matching retirement fund to 50 percent of your salary, and a company car leased every two years, say, a red Corvette?”

The applicant sat up straight and said, “Wow! Are you kidding?”

And the interviewer replied, “Yeah, but you started it.”

-from Recruiters Network

Over the years, I’ve negotiated much more on my own, another car, home prices, salaries, etc. While I’m still very far from as proficient as I’d like to be, these experiences have taught me what to do and what are my weaknesses.

Create Objectivity by Having Someone Negotiate for You

A tip I learned from You Can Negotiate Anything is to ensure an objective party is negotiating for you. Because emotions often get in the way of logic, having someone who is invested only in reducing price can be highly beneficial. Relating this to my story above, my mom should have been objective in the situation but her own emotions were in play. She wanted to make sure I had a car so I didn’t have to borrow hers anymore. She did not want to experience the “pain” of lending her car any longer and was willing to have me pay to get my own.

Willingness to Walk away

The number 1 rule of negotiating is being willing to walk away from the deal. This gives you leverage.

In my example above, my mom was not willing to walk away, because she wanted me to have my own car. In other practical scenarios, this rule means that no one will give you a better price if he or she thinks you are going to buy something anyway. In contrast, if he or she senses your willingness to not come to an agreement, he or she will be more likely to meet your demands.

Collaborate on Less Significant Issues

Sometimes either party will not budge on the main issue, such as price. However, it can be possible to come to agreement on other items that are more significant to one side than the other. In the above example, this meant getting more free maintenance. In salary negotiation, it might mean getting extra paid time off or tuition reimbursement instead of a salary increase. There are many ways to add mutually beneficial clauses to meet in the middle of a negotiation. Additionally, this strategy is much less confrontational.

“If I give one to you, I have to give one to everybody else”

When going into a negotiation, make sure you understand the worst case scenario. Where possible, prepare beforehand to improve the worst case scenario. If missing out on a job opportunity means not having a job, then you can improve the worst case scenario by trying to line up a second job offer. Little tips like the ones above, plus many others, can help to make you a deadly negotiator, and as with anything, practice makes perfect.

How to Generate .NET Classes from a Non-.NET Data Feed

Most people do not realize how much data is available on the web via APIs. Indeed, we .NET programmers tend to be a breed that ignores the trendy new data feeds that are available. Perhaps it’s because it is intimidating to try to interact with sites written in PHP or Ruby on Rails or maybe it’s because the only examples anyone ever shows are for Netflix or Twitter APIs (2 APIs that are not particularly useful for an Enterprise Developer). Now is the time to expand your horizons. As more and more data becomes available, the usefulness increases for all types of applications. I aim to broaden your awareness of the entire domain of public web services (APIs) and show you that

  • .NET can be a great client coding-language for any standard web API
  • There are great online resources to find available APIs.

 

Table of Contents

Before I dive head first into all the details, here is an outline of what I will cover and the basic steps involved:

  1. Purpose/Intention
  2. Choosing an API
  3. Review Documentation
  4. Determine a Sample Query
  5. Generate Classes at Json2CSharp.com
  6. Paste Generated Classes into New Application
  7. Massage Generated Classes
  8. Reference Json.NET
  9. Retrieve Data with a WebClient Object
  10. Display Results within Application

 

Purpose/Intention

At this point, you may be asking yourself, “why do I care about Data Feeds, APIs, and public Web Services”? You should care because it is the technology through which online companies share their data. If you think it might be worthwhile to someday automatically retrieve the weather forecast, stock prices, sports scores, site analytics, etc. and make logical decisions based on the data, then pay attention because the steps that follow are how you get started. A well-known example of a website using a public APIs is Expedia.com, which retrieves commercial flight and hotel information from multiple providers based on a user’s travel criteria. There’s very little stopping us .NET developers from gathering together multiple APIs in a similar fashion.

 

Choosing an API

The first step of connecting to an API is to choose which one you will connect to. If you already know, you need to find out more information about it. To do this, I used ProgrammableWeb.com, an online directory of public-facing APIs. When I started the exercise for this blog post, I did not know which API I wanted to test with, so I just clicked on API Directory | Newest APIs. As tempting as it was, I chose not to use the Stack Overflow API, because it is already built in .NET and is therefore disqualified from this blog post. Instead, the API for the Khan Academy caught my eye.

In case you haven’t heard of it, Khan Academy is a non-profit organization that provides a wide range of training videos and courseware for free online.

The Khan Academy API is perfect:

  • It’s not a .NET service written in WCF (it’s Python)
  • I hear about the site all the time. It’s sexy right now.
  • It follows a web standard, REST formatted in Json.

By clicking the Khan Academy link in the Programmable Web directory, I was eventually taken to the Khan Academy API documentation site.

 

Review Documentation

Many large websites have thorough documentation about their APIs. Still, there is a wide range of information that you may come across when researching them. Some have client-side examples in .NET and others even have 3rd party libraries (e.g. MailChimp) specifically written for them. Khan Academy has a nifty tool called their API Explorer, which allows you to click on different types of REST queries and see example responses. . I’ve seen similar tools on other sites too, such as Yahoo.

 

Determine a Sample Query

To start creating our .NET client application, we need to determine a sample query and retrieve response data. I’d like to generate local, .NET classes to consume the information sent back from Khan Academy.

There are a couple different ways of thinking about this:

If I know specifically what type of information I will be using, I can look for documentation on how to retrieve that narrow result set. In this case though, I want to start with as many classes as possible, to fill out my .NET solution with a large portion of classes.

The playlists/library/ query is great because it returns nested results. So, for example, it has information for playlists, with sub-information about videos, tags, etc.

Having a sample response like this is half the battle, and it’s not that difficult to get for REST services.

 

Generate Classes at Json2CSharp.com

Once we know what sample query we are going to use, we continue to our 2nd big step, where we either paste a URL or Json results into a website named json2csharp.com.

This website converts the sample response data that we entered into .NET class definitions. With this step, we are letting the Json2CSharp website perform a significant step of the process for us automatically.

Why do we go through the effort to generate .NET classes like this?

  • It enabled compile-time checking and intellisense
  • Design-time use in Web Forms Gridviews, etc.
  • Can be used in older versions of .NET (earlier than .NET 4), which do not yet have dynamic objects.

 

Paste Generated Classes into New Application

Now that I have generated .NET classes, I will copy them into my Windows Clipboard (Ctrl-C) for later use.

Let’s keep things simple by creating a brand new Web Application. In Visual Studio 2012, select File | New | Project. Then select an ASP.NET Web Forms Application.

 

With the new application in place, let’s add the .NET classes into the solution.

First, add a class file to the project.

 

In this file, paste (the .NET classes that are in your Clipboard) over the default class. As a quick sanity check, you should be able to successfully compile the solution.

 

Massage Generated Classes

Json2CSharp sometimes struggles with ambiguous responses. As a result, it generates duplicate class definitions as is true in our case.

Still, it’s nice that the class generator got us part of the way toward our final code. Let’s massage our classes to remove any classes that have numbers on the end. Also, switch any reference to the duplicates back to the primary class.

Delete: Item2, DownloadUrls2, Video2, Playlist2, DownloadUrls3, Video3, Playlist3

Alter: References to Item2 -> Item, References to Playlist2 -> Playlist, Reference to Playlist3 -> Playlist

 

Reference Json.NET

In order to deserialize Json results into our generated classes, we need to use another 3rd party tool named Json.NET. To add a reference to this library, we can perform either of 2 methods:

Download and Add Reference

  1. Browse to Json.CodePlex.com
  2. Download the latest version as a .zip file
  3. Extract the relevant version of the Newtonsoft.Json.dll
  4. Add a reference to the dll

Install with NuGet

  1. In Visual Studio, go to Tools | Library Package Manager | Manage NuGet Packages for Solution
  2. Click Online in the left panel
  3. Click Json.NET to highlight that package
  4. Click Install

 

Retrieve Data with a WebClient Object

At this point, we’ve got the framework setup in our solution to store strongly-typed representations of the Khan Academy data. Next, we need to write the code to retrieve that data.

Here is the snippet I put in the Default.aspx.cs file to automatically retrieve the data and format it with Linq.

public static List<Playlist> GetKhanVideos()
		{
			var client = new WebClient();
			var response = client.DownloadString(new Uri("http://www.khanacademy.org/api/v1/playlists/library"));
			var j = JsonConvert.DeserializeObject<List<Item>>(response);

			List<Playlist> playlists = new List<Playlist>();
			playlists.AddRange(j.Select(i => i.playlist));
			playlists.AddRange(j.Where(k => null != k.items).SelectMany(i => i.items).Select(i2 => i2.playlist));
			playlists.AddRange(j.Where(k => null != k.items).SelectMany(i => i.items).Where(k2 => null != k2.items).SelectMany(i2 => i2.items).Select(i3 => i3.playlist));

			return playlists.Where(p => null != p).ToList();
		}

 

Display Results within Application

In our last step, we want to see the output of our query, so let’s leverage the drag-and-drop ability of Web Forms to easily visualize the data.

  1. Open Default.aspx in Design View
  2. Using the Toolbox, add an ObjectDataSource
  3. Configure the DataSource
  4. Choose WebApplication1._Default as the business object
  5. Choose GetKhanVideos() as the Select Method
  6. Using the Toolbox, add a GridView
  7. Configure it to choose the above Data Source
  8. Many of the fields will be empty or gibberish, so let’s remove several columns:
    1. backup_timestamp
    2. hide
    3. init_custom_stack
    4. ka_url
    5. kind
    6. standalone_title
    7. topic_page_url
    8. url
    9. youtube_id

To see the new application in action, press F5 to run it.

 

Conclusion

With the help of a few 3rd party tools, retrieving and displaying any REST-based API in .NET can be easy. Not only that, but it’s going to get even easier. In Scott Hanselman’s ASPConf keynote, he showed an extension that is being developed by Mads Kristensen for Visual Studio 2012 that would eliminate several of these steps. It allowed an option in Visual Studio to “Paste JSON as classes,” thereby eliminating the need for the class-generation website. Microsoft realizes that the trend of creating and leveraging public APIs is not going away so they are doing something about it. And so should you.

 

Disclaimer: This product uses the Khan Academy API but is not endorsed or certified by Khan Academy (www.khanacademy.org).

A Review of our Time Tracker Software

I work at a small, but quickly growing consulting startup. At first, time-tracking was a significant pain for me and the owner. I spent a lot of thought trying to automate my personal time-tracking and had decent success using FogBugz and Paymo. However, no matter what I tried, I was still required to spend about 3 hours a month (1.5 hours per billing period) exporting my time records into an acceptable MS Excel format to be given to the client. I understand that there was even more work done by the owner, as he made sure every consultant’s format was the same, copy-and-pasted records into one huge spreadsheet, and invoiced the client based on this report. What a mess! That was time that should have been spent on client work, advancing the projects to which we were assigned and making more money in the process. Thankfully, after some brainstorming and research, our company standardized on Harvest for time tracking.

What we wanted was an affordable, centralized solution that could track time and enable invoicing for all employees at the company. Harvest has delivered even more than we thought we needed! Included with our monthly payment, we receive a mobile app, API use, and expense tracking.


Harvest Time Tracking

 

Design

One thing I like about Harvest is that it is definitely a modern-looking website that is continually being updated. The site is also intuitive and visually appealing. It was not long before we learned how to make an invoice online.

 

Usefulness

Simply put, Harvest saves us time. What used to take me 90 minutes at the end of each billing period now takes me 5. It’s also very easy to manage and create invoices. I think it’s fair to say it’s worth the money considering we keep paying the fee every month.

In addition to its advertised features, online time tracking provides insight and transparency into key aspects of our business:

  • Employees’ work habits
  • Progress of projects and budgets
  • Real-time snapshots of what work is currently being performed

 

The Time Tracker App

Members of our team have used the Harvest Time Tracking app for Android and iPhone. It is pure icing on the cake. It has its limitations but it saves me a lot of time in 2 particular use cases.

Expense Tracking

I can easily keep my expenses organized with this app. The best feature is the ability to add expenses and to take a picture of any receipt as soon as I receive it. By making it so simple, it encourages the habit of inputting expenses almost instantaneously, reducing the likelihood of losing track of a receipt or forgetting about a meal. It can be humorous to see a few members of our team out to eat on a business trip as we all take out our phones to take pictures of our separate receipts.

Stopping a Running Timer

Simply explained, the smartphone app gives me mobile access to my online time sheet. This is especially useful if I leave the office to run an errand or go home for the day but absent-mindedly leave my timer running. I can quickly take out my phone, open the app, and stop the running timer. It syncs with the Harvest server soon after.

 

The iPhone app does have some limitations. The key item I’d like to see improved is the ability to edit time entries (which is possible on the website). As explained in my most common use case above, if I leave a timer running I might remember to stop it while I’m on the go. It would be nice to be able to edit the time entry to change the end time to be earlier (when I actually stopped working). As it is now, I have to remember to go back and change that time entry the next time I’m in front of my computer.

 

API

I’m not yet a connoisseur of web APIs, but Harvest seems to have a good one as far as I’m concerned. As an experiment, I wrote a simple website to display whether or not I am working at any given moment. You can see my site here, which I put together in just a few hours. Disclaimer: I wrote this website as a play project for my own utility. I reserve the right to take it down at any time.

 

Integrations

I haven’t yet had the need for many of these but it is encouraging that Harvest time tracking integrates with many common software-as-a-service tools such as InDinero, Twitter, ZenDesk, and HighRise.

 

Summary

It should come as no surprise that I consider Harvest to be some of the best small business software I’ve used. It runs the core of our business and draws few complaints. It’s especially easy to bring on new consultants, requiring almost zero training. In that case we typically say something like “just use Harvest for time tracking.” And they do…

Don’t Disrespect the Web.Config – ELMAH

This blog series has focused on simple changes that can be made to a .NET solution’s web.config in order to enhance the development environment, enhance security, and improve troubleshooting capabilities.

You can find previous posts here:

  1. Use web.config transforms to keep track of development versus production settings
  2. Encrypt important configuration sections for security
  3. ELMAH – Error Logging Modules and Handlers

This is the 3rd and final post of the series in which we discuss ELMAH, short for Error Logging Modules and Handlers. I am definitely not the first to write about this, but it is such a useful tool that fits snuggly into the web.config that I had to include it in the series.

 

What is it and why do I care?

First, let’s explain what ELMAH is. It is an open-sourced component that can be easily added to a .NET project for the purpose of logging and notifying developers of unhandled exceptions. What is an unhandled exception? It’s an error in code that a web application cannot respond to, often resulting in a “Yellow Screen of Death.”

ELMAH does not, by itself, rid your application of a Yellow Screen of Death, a screen that causes much frustration among users of your application. Instead, it automatically logs the details of the exception, and the stack trace at the time of the exception, and it can even email the development team that something bad happened.

Using ELMAH has become the standard for any project that I work on. It’s just so darned useful for troubleshooting issues and doing great customer service.

 

Typical Workflow of a User Encountering an Error

Most of the time, users encountering an error do not immediately send an email to support. If it’s a public website, the user might get immediately discouraged and leave the site. If it’s an Intranet website, one that users must use to perform their jobs, then he or she might back up and try it again a couple of times before giving up:

  1. Attempt to perform job function
  2. Curse at screen when exception occurs
  3. Try again
  4. Complain to boss when the same failure occurs
  5. Contact support
  6. Wait
  7. Lose faith in the developers of the website, the support team, and anyone else who is guilty by association

 

Workflow when Error Notifications are Involved

With ELMAH in place, it is easy to short-circuit the workflow and keep users happy. You can begin to troubleshoot the issue before the user has even contacted the support team.

  1. User attempts to perform job function
  2. User curses at screen when exception occurs
  3. Development team member is notified that exception occurred along with details
  4. As the user attempts to try again, the development team member can reach out to the user

    Hello [username],

    I work on the support team for [name of web application]. Our system automatically notifies us when users run into an error that it does not know how to handle, and we are aware that it affects your ability to continue through the application.

    We do not yet know exactly what the problem is, but are working to find out more information and resolve the issue quickly. I will let you know as soon as this is fixed.

    In the meantime, it would help us to resolve this more quickly if you could tell me [what steps you were performing when this crashed].

    Lastly, I know it is less than ideal, but you might try to [perform your job through this work-around or alternative solution] until I get back in touch with you.

    Thank you,

    [Nathan Stuller]

    [Title]

  5. Often, by the time the user would have contacted support, the issue is already fixed

 

Being proactive makes a serious impression on users (and bosses). I’ve used this technique before to reach out to customers about exceptions that they didn’t even notice. It reduced my stress level by confirming that it was a low-priority issue and also allowed me to engage with a customer about my product.

 

How to Get Started

The first step is go to the ELMAH homepage. There you will find the 2 most important links to enable this setup:

  1. Download links to the ELMAH dll you must include in your project
  2. A sample Web.config file (on the same page)

 

The Real Steps

  1. Download the appropriate binary to your web application folder.

  1. Open the zip file. Browse into the “bin\net-2.0\Release” folder and extract the Elmah.dll into your Libs folder.
  2. In Visual Studio, we need to make a reference to this dll from your main web project.

 

  1. Next, you need to add entries into the web.config to tell your project how to use ELMAH. The website has lots of information on how to do this, but I will try to simplify it for the common example of notifying developers by email. First, you need to add this line inside the <configSections> area of the web.config:

  1. Next, add the following line under the <httpModules> section. This may need to be altered depending on which version of IIS your web server is using:

  1. Lastly, add the elmah section (usually at the end) inside the <configuration> section:

There are a host of configuration options you can set to enable ELMAH to do exactly what you want.

 

Wrapping Up

I hope this 3-part blog series has helped you identify simple improvements that can be made to the web.config file. ELMAH, in particular, helps me delete my clients and since it is so simple to implement, to me it is a no-brainer.

Don’t Disrespect the Web.Config – Encryption

As stated in an earlier post…

There are 3 things every public website should be doing with their web.config

  1. Use web.config transforms to keep track of development versus production settings
  2. Encrypt important configuration sections for security
  3. ELMAH – Error Logging Modules and Handlers

In this post, we’ll discuss how to encrypt sensitive sections of the web.config so passwords and other information cannot be easily read by those who gain access to the file.

Why is it important?

Encrypting sensitive sections of the web.config is important because they are just that, sensitive. Think about your production web.config file. It may contain all sorts of data that you would not want to be accessible. There are often passwords for SQL database connections, passwords to an SMTP server, API Keys, or critical information for whatever system is being automated. In addition, web.config files are usually treated as just another source code file. There are probably many versions in your source control system right now. That means, any developer on the team, or more accurately anyone with access to the source code, can see what information is in the web.config file.

In many cases, storing passwords in a web.config is itself unnecessary and should be avoided. However, we know it is all too easy to fall into the trap of placing them in this flexible, convenient file. Therefore, at the very least, certain sections should be encrypted so they cannot be easily read or used for evil.

Encrypting ConnectionStrings

In our example, we will encrypt two typical configuration sections: ConnectionStrings and AppSettings on a Windows 7 development machine.

Follow the below steps:

1. Open a command prompt with elevated, Administrator, privileges:

2. At the command prompt, enter:

cd “C:\Windows\Microsoft.NET\Framework\v4.0.30319″

3. Now enter the following to encrypt the ConnectionStrings section:

aspnet_regiis.exe -pef “connectionStrings” “C:\WebApplication1\WebApplication1″

In this case, C:\WebApplication1\WebApplication1 is the directory where our web.config is located.

4. Enter the following to encrypt the AppSettings section:

aspnet_regiis.exe -pef “appSettings” “C:\WebApplication1\WebApplication1″

For reference on all the command-line options of aspnet_regiis.exe, refer to this MSDN page.

Decrypting ConnectionStrings

Of course, it is possible you might need to be able to read the original, unencrypted, data at a later time. To access that information is easy. Simply perform the previous steps but use the command-line option “-pdf” to decrypt the important sections.

Deployment

Deploying your web application with encrypted web.config sections is simple, but it may not be obvious. This StackOverflow answer explains the steps best. Generally, any server or development machine that uses the same encrypted web.config data must use the same RSA key pair, which can be exported using the aspnet_regiis tool.

Before and After

There you have it. You have successfully encrypted 2 sections of your web.config file. Take a look below to observe the before and after results:

Before

<connectionStrings>

<add name=ApplicationServices connectionString=data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true
providerName=System.Data.SqlClient />

</connectionStrings>

After

<connectionStrings configProtectionProvider=RsaProtectedConfigurationProvider>

<EncryptedData Type=http://www.w3.org/2001/04/xmlenc#Element
xmlns=http://www.w3.org/2001/04/xmlenc#>

<EncryptionMethod Algorithm=http://www.w3.org/2001/04/xmlenc#tripledes-cbc />

<KeyInfo xmlns=http://www.w3.org/2000/09/xmldsig#>

<EncryptedKey xmlns=http://www.w3.org/2001/04/xmlenc#>

<EncryptionMethod Algorithm=http://www.w3.org/2001/04/xmlenc#rsa-1_5 />

<KeyInfo xmlns=http://www.w3.org/2000/09/xmldsig#>

<KeyName>Rsa Key</KeyName>

</KeyInfo>

<CipherData>

<CipherValue>fK275KFHx9RKip16DTpwxLi4AHpvCpat4S3edgsDwco9PgudsMKc1qAyh9qNt2y+90qV4QIzyZXm8j27UV5J+R5rNruMUOROLWzVt8qkRYRM3ADoiCi5BJh2SsjE0guGXFbufZDgRpPFV5bstgZSBPYNiYXQF/aOLyQjPCE8VDo=</CipherValue>

</CipherData>

</EncryptedKey>

</KeyInfo>

<CipherData>

<CipherValue>CSdausUH7yWcY8t1sPUqiCooYreEauzi4t33gVJuWYcfhspsguTchJjwthUTMLqnulYRmCu8ZnhrVBepQo7PHO/4k5mwo3s46TsgFddvvUlyY/EDQf047LG0pocBDxL3MgIGf3b+atoG29Jg0Wnhj+M6urYG55Ko4nGp36JILQptlEn+sqCl2sQ99izykXtRWP7kC4tldO+YvBuZ7x8fyGoANwSKQFo7cH+dbydvCkRvaFQsRATdsQKGmSrXwIlkoNvxFb1CBPx0qDenyCs+vO4QyF2CZ8QB+UIJzA8EL7W/FovH5zDczjXQWTsFSmsI+vSojl9G9jSVLJFbwOpQBLIKxfximl5r</CipherValue>

</CipherData>

</EncryptedData>

</connectionStrings>

In a future blog post, we will discuss the 3rd party component ELMAH, which is vital to being notified when your users encounter exceptions in your web application.

 

Update 07/24/2012
It is possible to combine encryption with web.config transforms. I know this will work as I have done it before.

In my experience, I’ve done the following. I had to add an RSA section at the top of my web.config. For me, this went into my web.config.release as I did not encrypt my default/development web.config:

<configProtectedData defaultProvider=”MyRsaProtectedConfigurationProvider” xdt:Transform=”Insert”>
<providers>
<add name=”MyRsaProtectedConfigurationProvider”
type=”System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL”
keyContainerName=”NetFrameworkConfigurationKey_viternuscom”
useMachineContainer=”true” />
</providers>
</configProtectedData>

Also, the web.config sections need to be replaced at the section level. You cannot replace the name or connection string attributes. So, you can use something like the below configuration to replace the whole connection strings section in each environment:

<connectionStrings configProtectionProvider=”MyRsaProtectedConfigurationProvider” xdt:Transform=”Replace”>
<EncryptedData Type=”http://www.w3.org/2001/04/xmlenc#Element&#8221;
xmlns=”http://www.w3.org/2001/04/xmlenc#”&gt;
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#tripledes-cbc&#8221; />
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”&gt;
<EncryptedKey xmlns=”http://www.w3.org/2001/04/xmlenc#”&gt;
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#rsa-1_5&#8243; />
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”&gt;
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>fV3NsFhZR/l0/5nvioFfjwjhhauNUTR96fQOK3QeRTW05ERDAQrFGj9MBt5Jh7Ca4rIS2JZfOfNTjTxWiEp/tjk+9LXVyPKrJYMiNlYiUmZGfV/amPsLPmRm2pOEyKwJhJLN6NyZdht/xGrf1ClDKO6CG1ViA5pK5R8Db8X9ul4=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>        <CipherValue>eFvSbAzbVUzwa9Sl8V6t43kuwAcvmaPUjboSJ/oi+MMJXyqtqXS8dKSuxBy+E0rC8tUxxIfJppZNm+CCoKf9Rm39vW2flpgcsvm8ZNMekSf4r2GWYAvLw3vYvMBcbnFRqktlaM7cXia38+3KGN8skHzxioqrBgy2QQqqPWIPrmrCS440BRlXEck6XwAO9rZOERgM6+OtlRan4EuGoB0O4acJWbp51zWxkfzqxMb600BHkYzeIYkHH8GNvWo+LSQt6o+NYW+Q7sm/lLFY5hPp3pGTOygXPehT1b/3BWZM+1dJ5sh8sBXO+t5m7/Dzqt4nvMqArmdEUvQdhYAPauC3Uj9HjDFpHkbOjVEzohIvB0kJ1Wc3uP4VvE6CRMbAsrRiSNLDlT6OpXYVrArLk9c1bBA56nFXPMxLEpN1umRcCfaQY0qxKrZi/yJ8dKD/C/5Vo7o50f10jM9eUrt3/uS71bNJk5U9N7kO42tZZGXZMui51o6MWcYxSC7VQ3KdCpy6UacBnD8MYr7EHeZ591ATQds8dzcsXY7w6Lsg1pXLK74HqXMW/xDeLtBoWJxat9y+</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>

I hope this helps.

“What Makes a Nickname Stick?” – a Toastmasters Presentation

Today I present to you my 7th Toastmasters Speech. The focus of this speech is to prepare by researching the topic. The speech should be 5-7 minutes long.

Some of the feedback I received was that the speech didn’t fit the “research” tag in traditional sense. It also was short, coming in at only 4:45.

I thought the criticism was fair. However, in my defense, about half of my speeches are almost purely research related, about careers or technical topics. So, I didn’t feel like I had to prove I could do that. Also, this speech did require a fair amount of research (though I didn’t reference it specifically in my speech). I had to look up Cavaliers nicknames, accurate movie quotes, and search for the origination of nicknames for inspiration.

Here is one of the sites I used as a reference: 25 worst nicknames in NBA History

And if you were wondering more about that yearbook picture I refer to, here it is (I don’t remember being that much of a Surge fan):

Follow

Get every new post delivered to your Inbox.