Visual Studio Magazine is reporting that Microsoft has released Visual Studio SP1 and it is now available for download. Among other things the service pack addresses issues with general stability, the editor, the shell, and IntelliTrace. It also improves support for 64-bit environments, Silverlight 4, IIS Express and a variety other areas. A full description of the service pack is available from Microsoft Support.
Software Development
TFS Power Tools Get a Facelift
Today the Visual Studio Facebook page had an announcement about the availability of an update to the TFS Power Tools. Although I’ve been back in SVN-land lately this update is still pretty exciting. Given that my most popular post is Everyday TFS I thought my readers would find it just as interesting.
Per the announcement the March update focuses on three main areas:
- Addressed reported issues in the Backup/Restore Power Tool
- Fleshed out the Windows Shell Extension for version control
- Took the first step on the path to a bunch of new TFS Build Power Tools
Cincinnati Day of Agile
Over the years my team has followed very loose processes for software development. Now that we’ve matured as an organization we’ve found that the time for more formality is upon us. As such, we’ve started adopting Agile methodologies to help us stay focused and on track. With this change I thought it would be a good idea to get up to speed with what’s happening in the Agile world and what better place to do that than a day long event focusing on Agile?
The Cincinnati Day of Agile is on March 26th and is being held at the Savannah Conference Center. It runs from 8:00 – 5:00 and early registration is $50. You can find out more on the event site or registration site.
I hope to see you there!
NUnit and WatiN
Today a colleague was trying to diagnose why some long neglected UI tests were failing. He quickly discovered that the tests weren’t failing because of changes to the code under test but because our UI test framework was misbehaving. Since I’d been involved in developing parts of the framework he came to me to see what I remembered.
Our test framework is essentially a wrapper around WatiN that controls certain application specific tasks like logging in, navigating with our windowing system, or interacting with some of our more complex controls. These tests were failing because the framework wasn’t able to get a reference to our main application window so a null reference exception was being thrown. Now, we’ve made quite a few changes to our application but our windowing system certainly isn’t among them so why were the tests failing?
Flickr API Notes
Until recently I had been working on a flickr app for WP7. It was coming along nicely but then flickr had to go and announce an official app that will be released at the end of January. Even though I’m no longer working on the project I thought I’d share some of the things I learned about working with their API.
Getting Started
The natural place to start on the project is by reviewing their API documentation. For convenience the API index page lists API “kits” for a variety of platforms including .NET, Objective-C, Java, Python, and Ruby among others. I started by looking at the Flickr.NET library but didn’t like how it defined so many overloads for some of the methods and ultimately compiled most of the API methods into a single Flickr “god” class so I started writing my own framework.
The API index page links to some highlighted “read these first” documents most of which are all must reads but some of them can be easily gleaned from the rest of the documentation. The documents I found most useful along with some highlights and notes are:
- Terms of Use
- Encoding
- UTF-8
- UTF-8
- UTF-8
- User Authentication
- Three methods
- Web
- Desktop
- Mobile
- Despite being a mobile application the features offered by WP7 made desktop authentication a more logical choice.
- Three methods
- Dates
- MySQL datetime format
- Unix timestamps
- URLs
- Guidance on how to construct URLs for both photo sources and flickr pages.
Formats
We can communicate with the flickr API using any of three formats:
- REST – http://api.flickr.com/services/rest/
- XML-RPC – http://api.flickr.com/services/xmlrpc/
- SOAP – http://api.flickr.com/services/soap/
The REST endpoint is by far the easiest to use since all of the arguments are included directly in the URL as querystring parameters. Making a request is just a matter of constructing a URL and issuing a POST or GET request.
Responses can be returned in any of the three formats but we can also request responses in JSON or PHP formats by specifying a format argument. I used REST for responses too because the format easily lends itself to XML deserialization and greatly reduced the amount of translation code I needed to write.
API Methods
In general I found the API easy to work with. The methods are clearly organized and offer a very feature complete way to interact with the system. Although each exposed methods has some accompanying documentation that is generally pretty complete I found plenty of room for improvement.
My biggest gripe about the documentation is how incomplete some of it is. For example, several of the methods accept an Extras argument. The Extras argument is incredibly useful in that it allows additional information to be returned with the list thereby reducing the number of API requests we need to make to get complete information back in list format.
The Extras documentation lists all of the possible values but what it doesn’t include is what is returned when the options are specified (at least not that I found without actually making a request with the options). For your convenience I’ve compiled a listing of the output values for each of the Extras options.
| Option | Response | Notes |
|---|---|---|
| description | description element | Element content can contain HTML |
| license | license attribute | Available licenses |
| date_upload | dateupload attribute | UNIX timestamp |
| date_taken | datetaken attribute | MySQL datetime |
| datetakengranularity attribute | The known accuracy of the date. See the date documentation for details. | |
| owner_name | ownername attribute | |
| icon_server | iconserver attribute | |
| iconfarm attribute | ||
| original_format | originalsecret attribute | Facilitates sharing photos |
| originalformat attribute | The format (JPEG, GIF, PNG) of the image as it was originally uploaded | |
| last_update | lastupdate attribute | UNIX timestamp |
| geo | latitude attribute | See documentation for flickr.photos.geo.getLocation |
| longitude attribute | ||
| accuracy attribute | ||
| tags | tags attribute | Space delimited list of system formatted tags |
| machine_tags | machine_tags attribute | |
| o_dims | o_width attribute | The dimensions of the original image – I prefer url_o for this information |
| o_height attribute | ||
| views | views attribute | Number of times an image has been viewed |
| media | media attribute | |
| media_status attribute | ||
| path_alias | pathalias attribute | Alternate text to be used in place of the user ID in URLs |
| url_sq | url_sq attribute | The url and dimensions of the small square image |
| height_sq | ||
| width_sq | ||
| url_t | url_t attribute | The url and dimensions of the thumbnail image |
| height_t | ||
| width_t | ||
| url_s | url_s attribute | The url and dimensions of the small image |
| height_s | ||
| width_s | ||
| url_m | url_m attribute | The url and dimensions of the medium (500 pixel) image |
| height_m | ||
| width_m | ||
| url_z | url_z attribute | The url and dimensions of the medium (640 pixel) image |
| height_z | ||
| width_z | ||
| url_l | url_l attribute | The url and dimensions of the large image |
| height_l | ||
| width_l | ||
| url_o | url_o attribute | The url and dimensions of the original image |
| height_o | ||
| width_o |
Consistently Inconsistent
As complete and responsive as the flickr API is it isn’t without its share of annoyances. The biggest issue that is found throughout the API is the lack of consistency. The API is so consistently inconsistent that we can even see examples in the table above.
Just look at the options and responses. How many options use snake case but return lowercase attribute names?
Another example is found with dates. Taken dates are MySQL datetime values whereas posted dates are UNIX timestamp values. This means that anything using the API needs to handle both types. I understand not converting taken dates to GMT since they might be read from EXIF data but can’t we get a standard format and have the service handle the conversions?
The Overall Experience
As I mentioned I opted against working with an existing library like Flickr.NET so I was building everything from scratch. As such, I started building my own framework and found that in general, the experience was painless. The fact that the API is so flexible in terms of request and response formats makes it useful in virtually any environment. The completeness of the exposed feature-set also makes it easy to build a rich integration.
What’s Next?
I may have stopped development on my flickr app for WP7 but I’ve made such good progress on my framework that I’m strongly considering putting it on codeplex and finishing it. Right now it only supports the REST formats, doesn’t have any caching capabilities, and only works asynchronously but addressing these topics shouldn’t be particularly difficult. If anyone is interested in the project please let me know.
Scrapped
I’ve spent quite a bit of time over the last several weeks working on a Flickr app for Windows Phone 7. I was getting really close to having something to release to the Marketplace but then last night Flickr announced that they’re releasing an official app for both WP7 and Windows 7. Immediately after watching the video highlighting the features of the apps I decided to stop working on mine.
I was really happy with how my app was shaping up. It was interesting to see how many of our design decisions matched up. We both displayed interesting (explored) images, “my” images, and recent images from contacts in a panorama. For the photo view page I was using a pivot control with two items. The first contained details such as the preview image, title, upload date, and description. The second item was going to list comments. I was even thinking about including a map for geotagged images.
Ultimately though, I’m just one person and they’re, well… Yahoo! As nice as my app was turning out I just don’t have the resources to pull off anything near what they’re doing with Azure – mainly a live tile and cloud based state management. If the official apps work anything like what the video shows when they’re released on January 31 they’ll quickly become my go-to resources for all things flickr.
So even though I won’t be putting a flickr app into the Windows Phone Marketplace the project wasn’t a total wash. Until starting this project I didn’t really have any opportunity to work with Silverlight. By extension, I’ve never really done anything with XAML or the MVVM pattern either. Naturally, this project also taught me a lot about the flickr API since I chose not to use the Flickr.NET library.
Of course, I’ve already paid the developer registration fee so now I need to think of something else to build. In the meantime though I’ll be looking forward to the release of the official apps.
Indy TFS Discussion Resources
Thanks to everyone that came out to Indy TFS on December 8. I hope everyone that attended found some value in it.
A few people asked for the list of resources I gave at the end of the session so without further ado:
- Everyday TFS
- TFS Power Tools
- Team Foundation Check-Out Settings
- Diff/Merge Configuration in Team Foundation
Enjoy!
Building Strings Fluently
Last night I was reading the second edition of Effective C#. Item 16 discusses avoiding creation of unnecessary objects with part of the discussion using the typical example of favoring StringBuilder over string concatenation. The tip itself was nothing new, StringBuilder has been available since the first versions of the .NET framework, but it did remind me of something I “discovered” a few months ago.
Back in late July Esther and I took a week vacation. We rented a two story loft on a marina in southwest Michigan. It was incredibly relaxing and apparently more refreshing than I realized at the time. When I returned to the office the following Monday I was looking at a block of code that was doing a lot of string concatenation and decided to rewrite it to use a StringBuilder instead. When using a StringBuilder I follow the familiar pattern seen in most books and even in the MSDN documentation:
var sb = new StringBuilder();
sb.Append("Hello, Dave");
sb.AppendLine();
sb.AppendFormat("Today is {0:D}", DateTime.Now);
Console.WriteLine(sb.ToString());
For some reason though as I was writing code this particular Monday I noticed something that I hadn’t noticed before. I realized that StringBuilder, a class I’ve been using for nearly 10 years, implements a fluent interface! All of those familiar methods like Append, AppendFormat, Insert, Replace, etc… each return the StringBuilder instance meaning we can chain calls together!
Armed with this new knowledge I started thinking about all the places that code can be simplified just by taking advantage of the fluent interface. No longer do I need to define a variable for the StringBuilder and pass it to something. Instead, I can create the instance inline, build it up, then pass it along.
Console.WriteLine(
(new StringBuilder())
.Append("Hello, Dave")
.AppendLine()
.AppendFormat("Today is {0:D}", DateTime.Now)
.ToString()
);
Hoping I hadn’t been completely oblivious for so long I hopped over to the .NET 1.1 documentation and what I found was astonishing – this functionality has been there all along. I asked a few trusted colleagues if they knew about it and incredibly none of them had realized it either! How did we miss this for so long?
Unlocking Configuration Sections in IIS 7.x
One of our administration applications uses Windows authentication so we can manage some Windows services. In the past we’ve simply changed the authentication method in IIS Manager and moved on but when as we upgraded our development workstations to Windows 7 and IIS 7.5 we started seeing the error:
HTTP Error 500.19 – Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
The Detailed Error Information section gave a bit more information:
This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault=”Deny”), or set explicitly by a location tag with overrideMode=”Deny” or the legacy allowOverride=”false”.
The Config Source section was kind enough to narrow down the problem to the <authentication> element. Since we need Windows authentication for service administration simply switching back to anonymous authentication wasn’t an option. We really needed to unlock that section.
The page linked from the Links and More Information section has a ton of information about each of the status codes along with links to other knowledge base articles for more details about error conditions. According to the knowledge base HTTP Error 500.19 has nine possible causes. This particular issue is listed as issue 9 and is described in detail on IIS.net.
In short, IIS 7.x locking is controlled primarily by the configuration found in the applicationHost.config file located in the %windir%\system32\inetsrv\config\ folder. Unlocking the section is a matter of moving the security/authentication section to a new location element and setting the overrideMode attribute to “Allow” so it is unlocked for all applications. Alternatively, the security/authentication information can be duplicated into a new location element with a path attribute identifying a specific application to unlock it for just that application, leaving it locked for all others.
I opted for the later option and simply added a new location element. Since I was not only enabling Windows authentication but also disabling anonymous authentication I actually had to unlock both. When I was done my new location element looked like this:
<configuration>
<!-- Existing Configuration Excluded -->
<location path="Default Web Site\MyApplication" overrideMode="Allow">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
</configuration>
With that in place the error disappeared and I was able to use the application as expected. Unfortunately I did have some trouble actually editing applicationHost.config since I’m running Windows 7 on a 64-bit system and I needed to edit the file with notepad rather than my trusty Notepad++.
10/29/2010 Update:
A colleague pointed me to the “Feature Delegation” icon at the root (computer) level of IIS Manager (Thanks, Ryan). Clicking into the Feature Delegation page shows a listing of features and their current override setting. With few exceptions each of the features can be changed to Read/Write, Read Only, or Not Delegated. There’s also Reset to Inherited option to remove any customization.
Note: Each feature’s context menu includes a “Custom Site Delegation” option that allows the settings to be changed per site (i.e.: Default Web Site) but doesn’t go as far as individual applications.
Unlocking the sections via the Feature Delegation page would certainly have been easier than editing applicationHost.config directly and should be suitable for most development environments. I think I’d probably stick to editing the configuration file for a production server though just for that added layer of protection.
December Indy TFS Meeting
Mark your calendar for the second meeting of the Indy TFS user group on December 8, 2010. I will be presenting some tips for improving the TFS version control experience. In particular we’ll examine enhancing version control with the TFS Power Tools, replacing the default compare and merge tools, tracking changesets, and integrating some project management features into the version control workflow.
Location
Microsoft Office
500 East 96th St
Suite 460
Indianapolis, IN 46240
[Map]
Doors open at 6:00 PM with the meeting starting at 6:30. Pizza and drinks will be provided.
Register at https://www.clicktoattend.com/invitation.aspx?code=151824.