- September 2008 (5)
- October 2008 (2)
- November 2008 (4)
- December 2008 (3)
- January 2009 (3)
- February 2009 (2)
- March 2009 (5)
- April 2009 (9)
- May 2009 (3)
- June 2009 (9)
- July 2009 (2)
- October 2009 (2)
- November 2009 (1)
- December 2009 (8)
Friend's Blogs
One Year of Production ASP.NET MVC
Last week marked the one year anniversary our team’s first ASP.NET MVC application in production. We really have two different types of production. Internal and external. While an internal application might get used by 2 to 100 people, our external applications get used by millions. After chatting with some members of the team and looking at the source code from a year ago, I’d like to share some thoughts with you. Let’s take a look back into the past, all the way back to the year 2009.
What Did We Learn? Sacrifices Were MadeI’ll be the first to admit that the project wasn’t where most of us wanted it a year ago, but the sacrifices we did make were consolations we were willing to live with. The easy one to point out is stuffing objects/data in ViewData. This seemed like a good idea at the time (and it was fast), but just gets messy in a hurry. You wont find this in many places anymore. We’ve been cleaning up that sort of thing while we’re in those areas and things look much tidier now.
Flexibility Was AchievedThe ability to cover our code with tests in MVC was much easier than the previous code in WebForms. This has allowed our code to be quite malleable. There are still some areas that are harder to test, but they disappear each week as we simultaneously see our code coverage marks rising.
Treat Routing With RespectRoutes are great, but they’re better when created earlier rather than later. If you’re starting on something new, be sure you thinking about your route conventions towards the beginning of the project and not as an afterthought. Wanting to change these up after the application is in production, you might have to end up breaking URLs or having to do some re-writing. The other big factor is realizing your site’s information architecture and how this is important to your site’s URL/directory structure. Big bonus points if you can nail this down right away and not have to worry about it after version 1.
Comments From the TeamWith the ability to keep views small and concise I am left with significantly less (duplicated) code to wade through while working with CSS and jQuery. I've noticed a definite decrease in time spent working in individual files allowing me more time to spend on enhancements and improvements. This last year I've designed more pages and worked on far more new features than any other year before, and hoping to continue that trend into the next year. – Jessica
MVC provides the hooks to quickly and easily do what we want. Case in point, the other day using in our dev session looking at overriding a "default" page with a custom page just by the existence of the page (view). With webforms this is possible but it's a pain with the page controller pattern dictating the flow of things. This allows us to more quickly respond to the needs of the business with less code in a more discoverable location - arguing the code we implemented is much clearer than an HttpModule (with webforms). - Tim
What am I Looking Forward to in the Coming Year? Conventions, Conventions, ConventionsNothing new here. The more time we spend in our code, the more certain parts of it look alike. Humans are good at spotting patterns and our group is very “humany”. (If that word isn’t invented yet… patent pending!) In all seriousness though, adhering to conventions can greatly reduce the time to market for new features, just ask the Ruby crowd. We’re finding more and more opportunity for conventions all the time.
Builders/TemplatesEssentially just more conventions ideas. MVC2 will allow us to use model templates (like input builders in MvcContrib), that we’re likely going to be taking advantage of. The typical usage I’m seeing is input forms, but we don’t have tons of forms within our project. We do have a lot of code that can make use of jQuery and progressively enhanced displays as well as templating many of our repeated and/or similar models.
Thanks…Obviously we’re not the only ones out there who use MVC. There seems to be many that are blogging about the pros/cons as well as giving tips and tricks on how to make MVC work better. I just want to say thanks, and keep it up!
Why is CruiseControl.Net Hiding My Test Results?
Some time ago, I noticed a CruiseControl.Net build report with thousands of unit tests passed, zero failed and a dozen or so skipped, suddenly showing that no tests were run:

I immediately thought somebody did something really bad. After some digging, I found an error in the CCNET log file that indicated an error was thrown and swallowed during the parsing of the test results xml file. It was choking on an NUnit Row Test with a null character in a string. Here is the exception:
2010-03-02 13:45:25,567 [Project.Web:DEBUG] Exception: System.Xml.XmlException: '.', hexadecimal value 0x00, is an invalid character. Line 5901, position 160.at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
at System.Xml.XmlTextReaderImpl.Throw(Int32 pos, String res, String[] args)
at System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Int32 pos, Char invChar)
at System.Xml.XmlTextReaderImpl.ParseNumericCharRefInline(Int32 startPos, Boolean expand, BufferBuilder internalSubsetBuilder, Int32& charCount, EntityType& entityType)
at System.Xml.XmlTextReaderImpl.ParseNumericCharRef(Boolean expand, BufferBuilder internalSubsetBuilder, EntityType& entityType)
at System.Xml.XmlTextReaderImpl.HandleEntityReference(Boolean isInAttributeValue, EntityExpandType expandType, Int32& charRefEndPos)
at System.Xml.XmlTextReaderImpl.ParseAttributeValueSlow(Int32 curPos, Char quoteChar, NodeData attr)
at System.Xml.XmlTextReaderImpl.ParseAttributes()
at System.Xml.XmlTextReaderImpl.ParseElement()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlWriter.WriteNode(XmlReader reader, Boolean defattr)
at ThoughtWorks.CruiseControl.Core.Util.XmlFragmentWriter.WriteNode(XmlReader reader, Boolean defattr)
at ThoughtWorks.CruiseControl.Core.Util.XmlFragmentWriter.WriteNode(String xml)
Here's an example that again broke our results output the other day.

This version of CruiseControl.Net isn't the newest, and is older than the version of NUnit that is running. This may be fixed by upgrading CCNet, I haven't tried yet though. This is just meant to be a "heads-up" in case you run into the same issue.
Unfortunately, my answer to getting the results to show back up was to remove both row tests. If anybody can add more details to this (affected versions, fixes, workarounds, etc), it would be greatly appreciated by myself and hopefully somebody else.
What is Projection?
I think there’s great benefit in not only knowing how to design your code to use common patterns but also to be able to speak about them clearly and concisely to others. If I mention that the problem sounds like it could be solved using the Strategy Pattern, somebody who knows what I’m talking about shouldn’t need much more of an explanation than that. Knowing certain terms in code will help with communication. Obviously, the better your team is at communicating, the more successful you’re going to be.
Very Simple ProjectionI’ve seen the following code all over the place. It’s very common to turn one collection into another or loop through and capture certain properties of the items you’re enumerating. How often have you seen this code:
public IList<string> GetNames(IEnumerable<Person> people){
IList<string> names = new List<string>();
foreach (var person in people)
{
names.Add(person.Name);
}
return names;
}
This is simple projection, but languages are seemingly giving you better ways to achieve this same thing. I’ll get to that later.
Different types of projectionI see three basic types of projection. There are variations of these same ideas, but for the most part these cover the bulk.
- Selection: Imagine you have a collection of customers and you want only the email addresses, this is where selection projection would be used. This isn’t always a one-to-one relationship, your customers may have more than one email address (if you allow it) and you’ll end up with more items in the projected collection than the starting collection.
- Creational: This is the type of projection that returns new values from an existing collection. Below, you’ll see two concrete examples in C#.
- Transformation: Given a list of numbers, you want those numbers squared. This is similar to creational, because you'll be getting a new item, but it shouldn’t modify the elements in the original collection.
An example that lends itself well to the concept of projection is the following:
My user interface allows strings to come into my application. I want to transform these strings into tags like any blog post, video or photo might have assigned to it. I don’t want my tag service class to have to deal with strings, I want to give it a collection of Tag objects. How do I do this?
With LINQ, this creational projection was very simple:
public void SaveTags(IEnumerable<string> tagNames){
var tags = tagNames.Select(name => new Tag(name));
tagService.SaveOrUpdateTags(tags);
}
Another great use of creational projection are some of the usages I’ve seen with SelectListItems in the ASP.NET MVC space. Given a list of objects, create a list of HTML drop down items for a select list.
K. Scott Allen has a good write up entitled Drop-down Lists and ASP.NET MVC on this very thing. There are also many good examples over on the MSDN Visual C# Developer Center.
Your Thoughts on Projection…I see this pattern often enough but I don’t hear the term “projection” nearly as often. Is there a more common name to this that I’m not hearing or are people just not referring to it by this name?
Unique Keys versus IDs in Web Applications
An ID is a fine way to uniquely identify an object, the common usage is also very user un-friendly. A while back I was watching a presentation by Jeffrey Palermo on Community For MVC.Net, then later at a live presentation and discussion at the local user group in Cedar Rapids. Not that it’s a new idea, but the idea of a Key and the IKeyable<T> interface was mentioned. This idea being a unique, human readable string. Throughout the rest of this post, when I mention “ID”, I’m speaking of an auto-generated number or meaningless string. When I mention a “Key”, I’m speaking of a meaningful string identifier that gives some sense as to what it is representing when a human reads it.
IDs in an Web ApplicationSequential integers in a database are easy to come by and are guaranteed to be unique by the database. This makes things simpler since you’re not required to check for uniqueness. Another option is to use GUIDs. These are good because the chance of collision is extremely small and gives you hundreds of billions of combinations. Another unique ID that I’m seeing appear more recently is the incremented strings, where “ab89Fh” is the prior ID to something like “ab89Fg”. All of these solutions are great for keeping things unique from the data perspective, but are horrible for human memory.
Unique Keys in an Web ApplicationThe concept is simple: a human-readable key that uniquely identifies an object. Why is a unique human-readable key a good idea? A key that is generated from some meaningful text is likely going to exist within a URL when in a web application. This is good for many reasons:
- They’re easier to remember
- Search engines see them as text and not garbage.
- You can make some assumptions as to what the content is, given the key.
Use keys over (or in conjunction with) IDs. They’re nice, they’re good and you’ll love them.
More Resources- Phil Haack recently posted a good solution to using keys (or slugs) in your MVC application. With Phil’s friendly URLs, you don’t have to sacrafice your precious integer IDs either.
- Derick Bailey had posts last summer (2009) with some thoughts on Database IDs and the storage implications. (Good comments!)
Unit Testing Simple ASP.NET MVC Controllers
I have created enough simple projects using ASP.NET MVC with unit tests to notice a very helpful pattern. The following is a sample of a test fixture using RhinoMocks and NUnit to test a controller.
1: [TestFixture] 2: public class AdminControllerTests 3: { 4: private IFacilityRepository facilityRepository; 5: private IMeetingRepository meetingRepository; 6: private IUserSession userSession; 7: 8: [SetUp] 9: public void SetUp() 10: { 11: facilityRepository = MockRepository.GenerateMock<IFacilityRepository>(); 12: meetingRepository = MockRepository.GenerateMock<IMeetingRepository>(); 13: userSession = MockRepository.GenerateMock<IUserSession>(); 14: } 15: 16: [Test] 17: public void SaveMeeting_should_call_Add_on_MeetingRepository_if_MeetingId_is_zero() 18: { 19: // Arrange 20: var meetingData = new MeetingData { MeetingId = 0, FacilityId = 0 }; 21: meetingRepository.Stub(x => x.GetById(0)).Return(new Meeting()); 22: facilityRepository.Stub(x => x.GetById(0)).Return(new Facility()); 23: var controller = GetController(); 24: 25: // Act 26: controller.SaveMeeting(meetingData); 27: 28: // Assert 29: meetingRepository.AssertWasCalled(x => x.Add(Arg<Meeting>.Is.Anything)); 30: meetingRepository.AssertWasNotCalled(x => x.Update(Arg<Meeting>.Is.Anything)); 31: } 32: 33: [Test] 34: public void SaveMeeting_should_call_Update_on_MeetingRepository_if_MeetingId_is_not_zero() 35: { 36: // Arrange 37: var meetingData = new MeetingData { MeetingId = 1, FacilityId = 1 }; 38: meetingRepository.Stub(x => x.GetById(1)).Return(new Meeting()); 39: facilityRepository.Stub(x => x.GetById(1)).Return(new Facility()); 40: var controller = GetController(); 41: 42: // Act 43: controller.SaveMeeting(meetingData); 44: 45: // Assert 46: meetingRepository.AssertWasNotCalled(x => x.Add(Arg<Meeting>.Is.Anything)); 47: meetingRepository.AssertWasCalled(x => x.Update(Arg<Meeting>.Is.Anything)); 48: } 49: 50: private AdminController GetController() 51: { 52: return new AdminController(userSession, meetingRepository, facilityRepository); 53: } 54: }
The reason I’m being explicit about the term “simple” in this case is that the controller above that I’m testing doesn’t have much going on. It has some constructor dependencies (like all controllers with dependencies should), but that’s about it. The gist of the pattern is made up of three things:
- A SetUp method, via NUnit, runs before each test to create new, fake implementations of the dependencies. In this case I’m using RhinoMocks, but you’re not limited to that (see below). Declaring them at the class level is nice, it allows you to use or ignore them at your leisure.
- Creating the GetController() method constrains the creation of a controller to one place. This is good because your dependencies can change by adding more or removing existing dependencies. By creating one place to “new up” the controller, you only have to update one area when dependencies change instead of updating a constructor in each test. This isn’t anything new for unit testing, just a good practice.
- Finally, your individual tests can get a new controller and stub/mock/fake the methods of your dependencies at any time during the test method and assert values or verify behavior at any time during the test.
This pattern has helped me a lot; I wish I had this in mind when I was writing lots of unit tests for controllers a year and a half ago (so I didn’t have to go back and change some of them later).
Another isolation/mocking framework I like to use is Moq. For the above example, there is a slight difference in the way the same fixture is used. The following is the same tests using Moq.
1: [TestFixture] 2: public class AdminControllerTests 3: { 4: private Mock<IFacilityRepository> facilityRepository; 5: private Mock<IMeetingRepository> meetingRepository; 6: private Mock<IUserSession> userSession; 7: 8: [SetUp] 9: public void SetUp() 10: { 11: facilityRepository = new Mock<IFacilityRepository>(); 12: meetingRepository = new Mock<IMeetingRepository>(); 13: userSession = new Mock<IUserSession>(); 14: } 15: 16: [Test] 17: public void SaveMeeting_should_call_Add_on_MeetingRepository_if_MeetingId_is_zero() 18: { 19: // Arrange 20: var meetingData = new MeetingData { MeetingId = 0, FacilityId = 0 }; 21: meetingRepository.Setup(x => x.GetById(0)).Returns(new Meeting()); 22: facilityRepository.Setup(x => x.GetById(0)).Returns(new Facility()); 23: var controller = GetController(); 24: 25: // Act 26: controller.SaveMeeting(meetingData); 27: 28: // Assert 29: meetingRepository.Verify(x => x.Add(It.IsAny<Meeting>())); 30: meetingRepository.Verify(x => x.Update(It.IsAny<Meeting>(), Times.Never())); 31: } 32: 33: [Test] 34: public void SaveMeeting_should_call_Update_on_MeetingRepository_if_MeetingId_is_not_zero() 35: { 36: // Arrange 37: var meetingData = new MeetingData { MeetingId = 1, FacilityId = 1 }; 38: meetingRepository.Setup(x => x.GetById(1)).Returns(new Meeting()); 39: facilityRepository.Setup(x => x.GetById(1)).Returns(new Facility()); 40: var controller = GetController(); 41: 42: // Act 43: controller.SaveMeeting(meetingData); 44: 45: // Assert 46: meetingRepository.Verify(x => x.Add(It.IsAny<Meeting>(), Times.Never())); 47: meetingRepository.Verify(x => x.Update(It.IsAny<Meeting>())); 48: } 49: 50: private AdminController GetController() 51: { 52: return new AdminController(userSession.Object, meetingRepository.Object, facilityRepository.Object); 53: } 54: }Both of these examples are using the Arrange/Act/Assert (AAA) syntax. The idea is that you set up your context, run some code, then verify the results of your objects and/or system under test.
This has been a very good to me and a simple pattern for testing most controllers in many of the simple MVC applications I’ve worked.
How I Approach a Defect
Lately I've been tracking some of the steps I go through in a given day or week. I was fixing a bug the other day when I decided that I should write down all the mental notes I refer to when addressing a problem like a bug in code. These are questions I didn't always ask in the past and I feel they are valuable, so why not share them?
Here's a few questions I'll ask myself when I think I have fixed a defect.
Does This Solve the Problem?The first and foremost concern is fixing the problem. Do the changes I'm proposing actually fix the problem? Or do they defer it off elsewhere? I try to remember that "the fix" should actually fix the problem. This may seem obvious, but sometimes a bug fix only deflects the problem elsewhere.
Is This Flexible, Maintainable, Clear and Simple?Some of these may seem to overlap, so I'll describe what I mean by each of them:
- Flexible: Does this solution allow somebody else to easily change or add to the code I have written? I could probably fix an issue by adding a bunch of conditionals in a place they don't belong, but this is just duct-taping the broken code.
- Maintainable: Similar to the previous question, does my solution address the root cause? I could run a database query to correct some bad data from time to time, but this doesn't lend itself to fixing the root of the problem. It creates a maintenance nightmare and just ends up being a waste of time.
- Clear: Are the changes I have made obvious and discoverable? I work primarily in the ASP.NET world and there are many ways to write code that isn't obvious (what comes to mind right now is writing an HttpModule that does some work to modify a request/response). Slipping in some code that fixes a problem at an odd place is not a clear way to fix a problem.
- Simple: Do your best to stick to the simplest thing that works. I could implement a big system to address a problem that involves an editor and management tools. However, if I can fix the problem some of these won't even be necessary. Don't over-engineer the problem to make it a bigger one than it actually is.
Somebody once said "Always leave the code in a better state than when you found it." That somebody was Robert (Uncle Bob) Martin. It's great advice and when followed, you're creating a better product every day. I'm a firm believer in this motto because it works. Don't take shortcuts, you're only going to be spending long nights later on paying back the technical debt you've accrued.
Is It Covered with Tests to be Future-Proof?How do you prevent defects and bugs from popping up again? There are two ways I can think of. You write unit tests and keep them running and passing with every code change, or you hire a team of people to test every possible feature of the code every time a new feature or bug fix is added. Your most consistent option is also the cheapest, the former, unit tests and a CI environment. Write a test to confirm the defect then fix it. If you continue to keep your code in a consistent state of harmony, you're going to prevent defects from occurring and re-occurring. I could also point out that fixing a bug right away is 1000 times cheaper than fixing it after it goes into production, but you probably already knew that. ;)
The previous four questions are running through my head the whole time I'm addressing the issue. Once I feel I have them all satisfied, I go through a few more steps before having my code peer reviewed:
Is There Any Code that was Commented Out or Stale?If you're on board with never commenting out code I'm partially with you. I'll comment out code when running tests, but the real problem with commenting out code is getting that code checked into source control. I'll browse through my changes and make sure that I don't have any code that is commented out that I forgot to delete. While this has the benefit of maintaining a clean code repository, it's also quite embarrassing when somebody has to ask you to delete it because you forgot.
Additionally, productivity and/or refactoring tools may give you warnings of code that is unnecessary, unreachable, or just plain pointless. Delete those lines too, they're just making your code messy and nobody likes cleaning up a mess that isn't theirs.
Do Any Named Variables or Classes Exist that Aren't Clear?This one isn't always easy for me. It's hard to take yourself out of context for a moment to ask yourself if the names you have chosen are clear without knowing the bowels of the code. A class with a name of LabelRequest might make sense to me since I've been working on a customer product return service, but there could be a better name for it. Something like ReturnShippingLabelRequest is a bit more clear for somebody else entering that area of code for the first time. Either of those beats "LR" though.
Are All Changes Relevant to the Fix?Lastly, it's important to ask yourself if all code changes that are being reviewed are applicable to the fix. Make sure there is nothing like "I also cleaned up 15 other files" going on in your request for review. These are red-flags that a code reviewer should probably point out to you, but if you can catch them before somebody else, you're just saving some extra time for everybody. Additionally, if I'm reviewing thousands of lines of pointless code changes mixed in with some critical code changes, I'm probably going to get lazy with the review and miss something. Keep it relevant and you'll keep the code reviewer astute.
By no means is this list all-inclusive and perfect; I'm just sharing what is currently working for me and my team. Feel free to leave me any comments or suggestions on thoughts/questions you consider when fixing a defect.
***UPDATE***Why all of you are terribly wrong about the Apple Tablet
Why all of you are terribly wrong about the iPad Apple Tablet
Let me start by saying these two things: One, I will never call this thing the iPad, I’m sorry – iSlate was such a better rumor I refuse to call it the Fujitsu encroaching, feminine hygiene product related name. Two, I have no idea whether or not I want an Apple Tablet. I’m pretty damned sure I do not want version 1, however I don’t think it is a complete failure, and I think a lot of ideas out there about why this device is terrible are absolutely wrong. I’ll start with the one that pisses me off the most:
Flash. Listen, people, and listen carefully. Adobe and Apple? They’re not friends anymore. They haven’t been friends since Adobe gave Apple the finger on the PowerPC -> Intel shift and Adobe took an entire year to develop a Creative Suite for the new processor. If you think Adobe was caught off guard by this Intel chip change, you’re dead wrong. That wonderful new A4 chip that’s appearing for the first time in the Apple Tablet? It was developed from the P.A. Semi company purchased by Apple in April, 2008. That’s nearly a year and a half before the first development from that acquisition saw the light of day. This breaks down into two primary arguments – Adobe vs. Apple, and sheer technological differences.
- Jobs and Co. may not be inviting Adobe to the party anymore, but seriously, when companies get in a fight like this you don’t just send a dozen roses to make up the differences. Steve doesn’t make a whole lot of mistakes here, folks, and if he showed you a broken Flash input, I’m inclined to say that this man who headed the revolution of music sales, phones, and micro-purchases – well, he probably knows more than you, dear commenter, just deal with it. I’m fairly sure that The Jobs showed you that broken Flash input just so you could see it was still broken. We all know that HTML5 is where the future lies, do you really think that Apple is not playing a game, here? They still don’t even sell a Mac with Blu-Ray! Every move is coordinated!
- This thing is – for now – absolutely nothing more than an intensely glorified iPhone. There’s not a Flash plugin developed (appropriately and through the proper channels – see point 1) for the iPhone/iPod Touch – what makes you think there’s one for the product that I’m 99% sure Adobe never got to lay their hands on before it was announced? Even IF the Apple Tablet does eventually support Flash, it will be after some serious modifications. Flash is very easy to exploit and a varies in it’s implementation from version to version dramatically. This variance takes away from a “perfect” solution that these products intend to enforce: A uniform web experience – the same for you as it is for me, no matter what.
Now that we’ve covered flash (and I managed to almost entierely ignore HTML5) , I’ll touch on a few of the other issues I see here.
- Exchange support. Everyone I talk to says, “Well, it’s basically just a glorified iPhone.” - Let’s do a little compare and contrast here. There’s an entire page for the iPhone and Enterprise support. Tablet? Here’s the quote:
And iPad works with all the most popular email providers, including MobileMe, Yahoo! Mail, Gmail, Hotmail, and AOL.
- Handwriting input / Design. I know nobody wants a stylus (yuck.), Steve, but seriously – your device is going to miss a pretty critical aspect of life here by skipping on the Doctors and Professionals that don’t WANT to type things. Everyone knows that Text-to-Speech isn’t a valid option in a meeting, but EVERYONE takes notes – why do I need to waste my time dragging around my antiquated netbook or laptop to type a note to myself when I have your Tablet? Lord knows I’m not going to drop my Apple Tablet down on the desk and start virtually typing while I try to eye-contact my boss. They already hate it enough if we even dare to check our iPhones – looking up and down at them because we have no homerow is not going to help us – fix this shit.
- Pressure Sensitivity. Dear Apple – I know you don’t like Adobe, but seriously, you’re giving people a 10″ screen they can carry around and you’re not going to let artists have pressure sensitivity? You’re going to force them to pop out their underpowered Macbook Air’s and their Cintiq’s just to draw something? The whole idea of a Tablet is to accomplish simple tasks quickly, effectively, and on the go – that which my Phone cannot. You have emasculated an entire level of professional – one which is still a market that should be critical to you given the amount of people switching to digital art and OSX as their ONLY form of interaction with their corporate environment.
Now, I could go on and on about what is wrong with this device, but I want to tell you all a little why you’re absolutely wrong in thinking this device (or it’s product line) are going to fail:
- iBookStore – Napster and the iTunes Music store both launched in 2003 – iTunes in April and Napster in October. As of August, 2009 – Napster is not even in the contention. Now, I’m aware that Napster’s business model is dramatically different these days than when it launched, but let’s face it, not even Rhapsody is up there on that list, and even Amazon – The undisputed internet sales website – can’t compete appropriately. Just because Apple missed the eBook revolution from the Kindle, etc does NOT rule them out of the game. The Audiobook revolution is high – something the Kindle can’t do – so even if folks aren’t interested in reading their books, the new Tablet can read it to them. Hell, they might even use Audible to do this, which is owned by Amazon!
- Truly perfect applications. While multitasking and it’s apparent lack-of is the bane of apparently every single person on the internet (trust me – I disagree, too), the idea that an application is going to be able to do one thing PERFECTLY (theoretically) for me is exciting. Gone are the days when a Mail client pretends to be a calender because there’s a calender app that can do it better. The same goes for all of those independent apps from the App store. Convertbot is better than anything I own when it comes down to conversion and that’s because it’s been designed – from the ground up – to be perfect as a conversion program. Dashboard as an Operating System. Simultaneously terrifying and awesome, this is a product line I am excited for (read: Google Wave) and terrified about (read: Microsoft Office). Hopefully it forms the best of both worlds.
- Finally – Apple Tablet v. 2.0 – Let’s face it. Anyone reading this post is really looking forward to version 2. Just like version 1 of the iPhone sported the most amazing revolution to Phones in quite some time, I think this device provides a very quantifiable leap in portable computing. However – it was not until the App Store that the iPhone made a difference. While that might have been a software release – I’m pretty sure that this first (max)iPad will be a Proof-of-Concept for the Second Generation unit. While this might not count as why THIS version is great – saying that the iPhone wasn’t exciting when it came out would have been a flat lie. Just because you expect more from a company doesn’t mean they’re not going to be cautious stepping into a very very very underrated market. Introduce a product that grandma can get used to because she managed to figure out how to use your iPhone? Yes, absolutely. Specialize that product to do more than just one thing at a time? This is how you learn and train
This list is just a start. I could go on and on about how much I absolutely !@#$ing hate this guy, but I won’t for now. Let me know what you think, kind reader.
***UPDATE*** – According to this article, Steve Jobs has apparently told his loyal Apple employees very much the same thing I said:
Jobs also singled out Adobe, calling the company “lazy” because, in his opinion, “they have all this potential to do interesting things but they just refuse to do it.” Jobs also criticized Flash for being buggy. When a Mac crashes, it’s usually because of Flash, he reportedly told the crowd. “The world is moving to HTML5,” he said.
Reading Code, Spark’s Once Attribute
For those who don’t know what Spark is… Spark is an open source view engine for Castle’s MonoRail Project (version 2.0 just recently released!) and ASP.NET MVC. The creator of Spark, Louis DeJardin, came up with the project in a comment left on a Phil Haack blog post amidst people complaining about the “tag soup” in the default view engine.
There’s a handy feature of Spark that allows you to specify a block of code that is only output one time to the overall view. This is especially nice when you have small partial files (similar to user controls if you prefer that term) that add some functionality that includes a JavaScript file. The Spark ‘once’ attribute allows you to name an include that will only be rendered once per name.
1: <script type="text/javascript" src="jquery-lightbox.js" once="lightbox"></script> 2: <script type="text/javascript"> 3: // ... do something 4: </script>Later on, possibly in another partial, you might need this same functionality again. The second time around, you’re only going to render that script tag if it hasn’t yet been written out.
This seemingly simple implementation in a view engine was interesting to me in that I was curious to find out how it was implemented. If it was easy, why wouldn’t something like this be in the default WebForms view engine?
I thought I’d take a look by browsing through the Spark code…
How Spark WorksIn very simple terms, the Spark view engine is a collection of TextWriters under a string parser; strings are read by the parser and turned into compiled code. Anytime you use a named content section, you’re essentially naming a TextWriter to which all that content under that name will be written. (It really is a Dictionary of string keys for TextWriter values.)
When the view is parsed, Spark uses the Visitor Pattern to handle each node that is contained within the view. Below is the implementation of IsSpecialAttribute by the class OnceAttributeVisitor. The visitor pattern is implemented in Spark in that there are different kinds of nodes that inherit from “Node”. Some of these classes need to tell their consumers whether or not they are “special”. Spark visits all nodes with 11 different Visitors, we’ll be looking at the OnceAttributeVisitor.
1: protected override bool IsSpecialAttribute(ElementNode element, AttributeNode attr) 2: { 3: var eltName = NameUtility.GetName(element.Name); 4: if (eltName == "test" || eltName == "if" || eltName == "elseif" || eltName == "else") 5: return false; 6: 7: if (Context.Namespaces == NamespacesType.Unqualified) 8: return attr.Name == "once"; 9: 10: if (attr.Namespace != Constants.Namespace) 11: return false; 12: 13: var nqName = NameUtility.GetName(attr.Name); 14: return nqName == "once"; 15: }After the code is parsed successfully, Spark will generate code from this translated view to be compiled. Any element that contains the ‘once’ attribute, like the script tag in the first code block, will create a call to a “Once()” function, passing in the value of the once attribute. (“lightbox” in our example above)
1: case ConditionalType.Once: 2: { 3: CodeIndent(chunk) 4: .Write("if (Once(") 5: .WriteCode(chunk.Condition) 6: .WriteLine("))"); 7: }When that code is compiled, it’s turned into a derived type of SparkViewBase, which, implements the Once method. The element that contains the ‘once’ attribute is only rendered if the Once method below returns true.
1: public bool Once(object flag) 2: { 3: var flagString = Convert.ToString(flag); 4: if (SparkViewContext.OnceTable.ContainsKey(flagString)) 5: return false; 6: 7: SparkViewContext.OnceTable.Add(flagString, null); 8: return true; 9: }The underlying type of OnceTable is Dictionary<string, string>, basically, we’ll allow the output a string value if the string key hasn’t already been registered in the table. The first element that is added to the OnceTable “wins” and will be the only output for that given key of all the elements that contain the same value in their ‘once’ attribute. All subsequent occurrences with the same attribute value will be ignored.
SEO Tips for Developers : Site Structure
Continuing in this series of tips for improving your search engine goodness, we’re going to take a look at some tips to designing the structure of your site so that it is friendly for our robot/spider friends.
Easy to Read URLsThis might be obvious to some, but maybe not others. URLs such as http://www.lostechies.com/blogs.aspx?blog=52&post=12923 do not have any meaning at face value; I can’t figure out what is on that page unless I click. People don’t like these and the bots don’t either. Strive for URLs like http://www.lostechies.com/blog/chris-missal/seo-tips-for-developers-site-structure or something similar. Given some certain situations, these aren’t always easy to come by. However, if you’re designing a site from scratch, give this high priority!
Good HyperlinksGive your users the ability to navigate your site no matter what page they’re on. Dead-end pages and the required usage of the back button is frustrating. You want actual links too, not JavaScript links or the “post-back links” that ASP.NET WebForms provides. Not only are they good for human users, but the spiders will follow them better too.
Ensure that links pointing back to users’ personal sites or other hyperlinks of which you don’t have immediate control, take advantage of the rel=”nofollow” attribute. This encourages search engines to treat the link with little or no weight towards that page. This helps keep your page’s importance higher. If the link is relevant to the content of the page, keep it normal (without the attribute). In other words, do good deeds and don’t try to “game” the system.
Your Site TemplateBased on some of my experience, here’s a few pointers I can share on how to template and build your pages.
- Every page that has unique content should have a unique title. Avoid missing or duplicate titles on your pages. This can be tricky when you have lots and lots of overlapping, dynamic content results.
- Make use of the important elements: h1-h6, title, strong, a. These should be used appropriately for the content they’re describing and linking to. These elements carry the highest values of importance across your page. Do your best to connect them to the structure of words that describe your data.
- Similar to point #1, keep your content canonical. This means there should be one location to access that information, not many. By producing one “true location” to the source of the data, you’ll make that page the most relevant place to go and less diluted. Produce canonical or normalized URLs. (see <link rel=”canonical” />)
It may sound a little hokey, but done correctly, these tips can be huge game-changers for you site. Bumping your pages up to the front page of Google gives you far more exposure than the second page and it only gets worse as you go further down the page list.
SEO Tips for Developers : Page Speed
I have been paying a good amount of attention to Google search engines since I started at my current job almost 3 years ago. Working on a public web site has more of a need for creating a robot friendly, content rich web pages than an internal web application. I don’t like to keep things to myself (I find it rude) so I thought I’d share some quick tips. These are more aimed at developers, than designers or content writers, of web sites.
Speed, speedier and speediest!The start of a new year is always a good time to begin something new. Google has decided hinted that they’re going to begin giving higher page rank to faster web sites. This makes sense, I don’t want to click on the first result if it is dog-slow, I’d rather click on something almost equally relevant that is faster. As a developer, think about how you serve the requests that are made. According to Google, a page loading in 1.4 seconds isn’t even in the top 20% of all measured web sites and 3.2 second page load is in the bottom half.
Enable compression of the files you sendHow do you do this? I’m not going to explain it when there are so many others already have (much better than I could too!). A simple search will give you plenty of results describing how to enable this with your specific server set-up. Even fellow blogger Keith Dahlby describes how to enable this in IIS.
Send fewer bytes per fileThis one is beneficial two-fold. The first gain is going to be quicker downloads to the client and the second is that the browser can “paint” the page faster; especially if you’re doing any kind of DOM manipulation when the document is ready. This is also relevant for your images, the smaller the file size, the faster the download.
Minify JS and CSS filesWhile similar to the previous tip. This is different in that you remove comments and whitespace where available. Depending on the size of your JavaScript and CSS files, you can save quite a lot by doing this. You obviously don’t want to keep them minified in source control, so do this as part of a build or deployment process.
I think it’s common for developers to look at server code when thinking about performance. Not only do you want your C#, Ruby or Java to run quickly, but also all the tiny pieces that tie things together. You’ll likely find bigger gains in some of these tips than in others, but even the little things can help you in the long run. Imagine increasing your traffic by twenty times? What about new features slowly adding more “bloat” to your pages? It’s the little things that can help combat those types of speed bumps.
That’s going to wrap it up for now, there will be more SEO tips for developers to come later. If you want to know more details of how I’ve accomplished these speed tips, hit me up on Twitter (@ChrisMissal) or leave a comment!
Also, here are some helpful links, use them, know them:
Chris’ Year in Review 2009
Last year on this day, I wrote a review of 2008 and some goals for 2009. I had not yet started blogging for Los Techies yet, but that started at the beginning of the year. Looking back on those goals, I think I did fairly well:
- Write a website application using Ruby on Rails : I did not write a full blown application, but I did learn a good amount and wrote several small applications for demo purposes using Sinatra.
- Blogs as Series of Posts : I wrote one series of posts entitled “Anti-Patterns and Worst Practices”. It seemed to go okay, there was a good conversation going in the comments of those posts and I learned a lot by writing them and reading the helpful comments people had to offer.
- Give Presentations : My goal was only one presentation, but I gave four separate hour or longer presentations in 2009.
- Using jQuery to Create Rich Internet Applications : I gave this one twice, first in Cedar Rapids, IA and also in Cedar Falls, IA.
- Beginner’s Guide to Unit Tests : I co-presented with Tim Barcz in Cedar Rapids, IA for Iowa Code Camp III.
- How to do Virtually Anything With JQuery : Presented at Iowa Code Camp IV in West Des Moines, IA.
- More blog posts : My blogging goal for 2009 was to produce 72 blog posts. I fell way short of this on Los Techies, but if you combine all the blogs I write for, I was right at that mark.
- Two or more commits to Open Source : I had many more than two open source commits. Most were related to documentation so they weren’t too valuable. I did learn that it’s not a great idea to look for places to commit code to open source, but more beneficial to try to use a project and add to it where it’s lacking.
I wish I could say that I met or exceed all of those 5 goals, but I did not. I’m still happy about what I learned For 2010, I’ll be attempting the following:
- Read the “Must Reads” : There are several books out there that people will state that every software developer must read. I’m going to try to read 4 or 5 (or more) of these “must reads”.
- Meet my failed blog count from last year : I attempted at 72 blog posts for 2009 on Los Techies and failed. It’s not because there wasn’t 72 things I wanted to write about, but because I didn’t take the time to write them all down. I’m going to attempt this number again, like 2009, I won’t let myself just churn out pointless posts to meet that number. I’ll continue to write posts that I think people can get something out of.
- Learn a new Language* : Normally I’d put this on my list, but I’m still working on getting up to speed with the Rubyists and I’m thinking I’m going to be spending tons of time on the books from point #1. I feel like I know enough about several languages to be dangerous, but I know I can learn much more in them all.
This post kind of makes me feel like I’m sharing too much information. I mean, who really cares what I’m working on besides me, my friends, and maybe my employer. However, the real reason I’d like to get these things out in the open is to get some extra feedback and hear what you’re shooting for in 2010.
- What are some of the “must reads” that I should consider? Please note: Don’t assume that I’ve read any of these, my library is a lot more lacking than I’d like it to be.
- By blogging more, what are some previous posts that were interesting? What should I continuing or start writing about? What should I stop writing about?
- What are some goals that you’ll be attempting next year?
- Any other kind of feedback for me personally or for Los Techies as a whole?
Thanks for you readership! Cheers to a new year!
Pablo In Print
Because of things like feed readers, many of you reading this may not visit the LosTechies home page very often. I just wanted to share with you that Jason has posted some links to print articles and/or books that our bloggers have had published.
Chad Myers, Eric Anderson, Jimmy Bogard and Derick Bailey have headed up this list with books and articles from over the last year or so. Keep up the great work guys!
Practices of an Agile Developer
Before I was even finished reading "Practices of an Agile Developer" by Venkat Subramaniam and Andy Hunt, I realized that it was going to exceed my expectations. I consider a lot of the practices in which I'm engaged in daily to be good agile practices. It wasn't until I read Venkat and Andy's descriptions of them that I truly appreciated the practices I regularly partake and learned about many others that I'm not participating.
The authors describe 45 practices in the book. They go over things like "What it feels like" and "Keeping your balance". The signs you'll notice and feelings you'll feel when you're doing it right, and pointers on not getting in over your head.
I can’t cover them all, but I’d like to touch on a few that stuck out in my head.
The BadThere were a few practices of which I would say I’m not doing a good job. I wouldn’t have read it if I didn’t think I’d learn something right? Here are few I noted that I couldn’t relate to when reading “what it feels like” when you’re doing correctly.
Be a MentorAside from helping others out at work or going over code after user groups and code camps, which I wouldn’t consider mentorship, I’m definitely not a mentor to anybody. The next closest thing would be blogging and presenting at code camps and user groups. I have done this so I’d say I’ve participated in some type of mentorship, but there’s still much room for improvement.
Keep a Solutions LogWith the combination or mix of unit testing, test driven design or just test first, I usually think I do a decent job of eliminating defects early in the development process. There will be bugs that show up from time to time though. One thing I’m not as good at doing is keeping a solutions log. At work, we use Trac for our defect tracking tool and I’ll find myself getting lazy and adding something like: “Fixed with revision 6230” or something to that effect. I may not always noticed, but the details of the defect sometimes aren’t written down very well. We might have the result of the bug and how to replicate it, but when closing it with some boring message like I stated above. Another developer viewing it later on might not understand the full implications of the problem. Within our team, questions have risen about previous fixes and I wasn’t able to articulate them as well as I wished I could have. The authors suggest that it should feel like an extension of your brain… I’m not recording enough to be at that point yet. I’m good about recording the “what” and “when”, but working on improving the “where” and most importantly, “why”.
The GoodThere are recommended practices that I think my group and I follow quite well. I selected a few to talk about that I think are very important and I’m proud we’re doing so well at keeping up with these.
Criticize Ideas, not PeopleI work on a team that is very open and honest. Sometimes I’ll forget I’m not at work and be very critical of something that somebody is doing. People don’t always take kindly to criticism, so I’ll get dirty looks. Within our team this type of criticism is not taken personally; we’re all part of the same team trying to do the best job we can for our company. I’m also lucky to work with a group of individuals that focus on quality and aren’t just there to collect a paycheck so they can spend it on the weekends. Because we’re often criticizing ideas, questioning the “way things are” and continually improving our process, we’re creating a better work-place for ourselves.
This practice talks about how you can interact with your colleagues to create an environment of respect, trust, pride and cooperation. Venkat recalls and talks about a real-life scenario where he learned a valuable lesson from a senior administrator. This senior admin could have pointed the finger, but decided to remain calm and help him with the fix. By working together they were able to fix what they needed and made everybody happy. This reminded me of the Collective Ownership practice the authors mention in Chapter 8.
Keep it ReleasableSmall iterations and a short feedback loop make keeping it releasable easy. If you’re always making sure that you keep the code base in better condition than when you left it, you shouldn’t have a problem with this. The single best way to do this that I can think of is running unit tests in a continuous integration environment. The best part of this practice is that you can do it for free. Andy and Venkat describe this feeling as though you can always show your latest code without hesitation or fear. The project is always in a ready-to-run, stable state.
Final ThoughtsMany of the books I have on my shelf are more of a reference book than books about ideas and practices. This one will continue to be an excellent resource for bettering myself as a developer and a team member. I’ll probably end up reading this book a few times a year just to make sure that I stay balanced!
The Razer Mamba for Mac – Complete review
The Razer Mamba. Arguably the most beautiful, if not the truly most spectacular “Gaming” mouse on the market currently. The Razer guys had truly out-done themselves with this piece of hardware in ever way. The problem, however, was the software support. Not for the PC, mind you – oh no, that worked just fine: For the Mac. Namely… there was none.
Until now.
The Razer folks have released their third major piece of “Mac” software. First it was the Deathadder, then the Naga, and now the Mamba! With the announcement of that piece of information – I decided to finally pick up some of their hardware I’d been longing after (though I would STILL like some valid Keyboard drivers, if you’re listening) and give them a full run-down.
My response? Meh…BUT.The reason I give the Mamba a Meh is NOT because of it’s hardware. This device is great – it is smooth, it is reactive, it is solid, it weighs what it should (if a little bottom heavy because of it’s battery), and dammit it is pretty (see the gallery). It gains my Meh because of it’s software. Here’s a list of everything the software can do:
- Enable Independant X-Y Sensitivity
- Enable Acceleration
- Change the Polling Rate of the Optical Sensor
- Turn on or off the battery / scroll wheel LED lights
That’s it folks. Oh, one caveat – You can ONLY DO THESE THINGS if the mouse is hardwired – when it is wireless, the software can’t even detect you have a Mamba plugged in. So, let’s just ignore that obvious bug and we’ll also toss aside the lack of full support for… well, what for? I’ll tell you what for:
How amazingly responsive this damned mouse is. I know it’s a stupid equivalent, but when I moved from a plain white piece of paper to a metal laser mousepad, the difference was immediate and I thought that was it. When I moved from my old Logitech to this guy… wow. And you know what was even more amazing? The top left buttons are actually active sensitivity changes – I can go up or down regardless of the operating system and it’s stored on the mouse – now that’s solid.
I’ll let the pictures and my video review do the rest of the talking but I’ll leave you with this: Even without software my Razer is worth a pretty penny. With Razer’s obvious point in beginning to adapt their software and drivers to a new platform, it is only going to get better and more full featured as time progresses, and for that, I cannot wait. Get me a keyboard and you folks might actually get me to leave the Logitech brand (lord knows their Squeezebox has me jaded almost entirely away from them)
The Mamba has landed!
Clay purchases legal copy of Win 7, Hell freezes over.
Today at approximately 10:49 PST, I purchased my first legit copy of Windows. Ever. I don’t count the stuff that comes packaged with my old HP or the Sony I had – both featuring Windows XP. I’ve been given various copies for my work in the tech field here and there (These things happen), but today, I purchased my first copy of Windows ever.
As an adamant pirater of things I could care less about – I have decided that purchasing Windows 7 is like a Pavlovian trigger for Microsoft to keep up whatever it is they’re up to. Hopefully next time they think about dropping a dead bird carcass off at my doorstop (Read: Vista) they’ll remember that the dozen roses they got me this year (albeit still mangled from their disgusting, dog-butt-breath and consumer-sharpened canine teeth) worked much better for allowing them into my house.
As a side note – I think I actually heard my Macbook cry a little when I placed the order – I made sure to use Safari.
Oh, and Hell? It just froze over.
Happy 1st Birthday, AppStore!

I could not believe that it has only been 1 year since the grand opening of the Apple iTunes AppStore. I guess it’s just been in the media and growing so fast it seems like it has been around much longer. 50,000+ apps are already available in the store. That is some major growth! Be looking forward to later this week for an annocement of a project I and some friends have been working on. I am quite excited about it!
Happy Independence Day!
Happy 4th of July everyone! What a great country we have!
As most all July 4ths, I spend it at the Okoboji lake with my extended family. It is a great time to see everyone and have some relaxing fun. On the night of the 4th, near Arnolds Park they light a great fireworks display right on the lake. Many boats drive over then drop anchor and tune their radios to the sponsoring station and wait for the count down of the show. Not only it is a great fireworks display, but the fireworks are perfectly timed with the music echoing over the lake with the occational boat honk for the favorites. The show included songs such as: Lee Greenwood (God Bless the USA), Neil Diamond (Coming to America), Louis Armstrong (Its a wonderful world), Ray Charles (America) and Elvis Presley (Glory, Glory Halleluliah), among others.
If you haven’t been to Okoboji – you need to make it out there at least once to experience the great show with your family or great friends. It makes my summer!

Friends at the Okoboji Fireworks 2009



















