With every release of the .NET Framework, more power has been placed in the developer’s hands. We can now concentrate on the overall process of our applications rather than developing the low-level functionality. In this post, I’ll start creating a simple RSS reader using ASP.NET and LINQ.
The first step is to decide how to define the RSS feed information and how our program will use it. The basic information we’re going to need will be:
For ease of maintenance, and to allow updating the list without having to edit our source code, we’ll store the feed definitions in an external file. There are many options for this and we’ll use the easiest option: XML. Our file will have a basic format, only storing the basic information that we need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!--?xml version="1.0" encoding="utf-8" ?--> <Feeds> <Feed> <Name>Stuck In Customs</Name> <Url>http://www.stuckincustoms.com/feed/</Url> </Feed> <Feed> <Name>2000 Things You Should Know About C#</Name> <Url>http://csharp.2000things.com/feed/</Url> </Feed> <Feed> <Name>There, I Fixed It!</Name> <Url>http://feeds.feedburner.com/ThereIFixedIt</Url> </Feed> </Feeds> |
We’ll store this information in a basic class:
1 2 3 4 5 | public class FeedDefinition { public string Name { get; set; } public string Url { get; set; } } |
Now that we have our feed definitions stored in an external file and a class defined to store the information, we need to load that data into our application. Before we had the .NET Framework, we would have to read in the file and create our own XML parser in order to load the data. This process has become easier with each version of the .NET Framework.
By utilizing LINQ, the process of obtaining the data from an XML file has become quite easy:
1 2 3 4 5 6 7 8 | XDocument feedDefinitions = XDocument.Load(Server.MapPath("Feeds.xml")); var feeds = from feed in feedDefinitions.Descendants("Feed") select new FeedDefinition() { Name = (string)feed.Element("Name"), Url = (string)feed.Element("Url"), }; |
Using just one line of code (line 1), the entire feed definition file is loaded and parsed for you. The contents are stored in an XDocument object. Processing this object using LINQ (lines 3-8), we obtain a collection of FeedDefinition objects (IEnumerable<FeedDefinition>) that we will use in our web page.
Now that we have our data, we need to be able to display it to the user. We will use a drop-down list control that will allow the user to select a feed for reading. In our ASP.NET content page, we’ll define the our display as this:
1 2 3 4 5 6 7 8 9 10 | <div class="feedList"> Feed: <asp:DropDownList ID="FeedList" DataValueField="Url" DataTextField="Name" runat="server" /> <asp:Button ID="OpenButton" Text="Open" runat="server" /> </div> |
The drop-down list box will be bound to our feed data that we read in earlier. However, we have two fields in our data. Using the DropDownList control, we can display the Name property to the user and use the Url property for processing later on.
Now that we have our feed definitions and our display, we just need to put them both together:
This code binds our feed definition collection to the drop-down list control. All we need to do now is put our code into our content page’s Page_Init method so that it’ll populate our control the first time our page is loaded.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | protected void Page_Init() { XDocument feedDefinitions = XDocument.Load(Server.MapPath("Feeds.xml")); var feeds = from feed in feedDefinitions.Descendants("Feed") select new FeedDefinition() { Name = (string)feed.Element("Name"), Url = (string)feed.Element("Url"), }; FeedList.DataSource = feeds; FeedList.DataBind(); } |
It’s important that you load the feed definitions in Page_Init() rather than in Page_Load(). Putting them in Page_Init() will prevent the drop-down list control from getting reinitialized during postback when we implement our Open button in Part 2.
When we load our website, we get our list of feeds neatly displayed in our control:
In this post, we wrote the first half of our simple RSS reader web application. By using the .NET Framework and the LINQ feature, we were able to load a list of RSS feeds into our web page without writing a lot of code.
In part 2, we’ll show how to get a list of posts from the feed and display them along with other data related to the posts.
Those that know me hear me say often that “I hate computers.” The first time someone hears me say that, their comment is usually “But, you make your living with computers!” I have to politely tell that it doesn’t mean I have to like them.
I was recently working on an issue discovered by our QA tester. We have a feature that allows access to dBase database files. As most programs that provide this access, we utilize the Microsoft Jet Database Engine to perform the heavy lifting. (I know, Jet is on it’s way out, but for now it still works.)
During my development, I tested this feature many times without any problems. Now, our QA tester opens a problem ticket stating that he cannot see any of the database’s columns. I attempt to duplicate it but cannot on my development machine, so I turn to one of my test machines.
Using a few different machines, I find that the issue is not the test file or the version of the operating system. What is strange is that I can get it to work on one machine but cannot on another with the same operating system. What’s worse, is that the error is not throwing an exception so my utility is not displaying anything to the user.
I do manage to finally get the application to throw an exception. What’s strange is that the exception message is “Microsoft jet database engine could not find object ‘xyz.dbf’”. SAY WHAT??? Not possible, the file is RIGHT THERE!!
Next I turn to my favorite tool, the web search. A bit of searching turned up the following interesting text:
3011 – Microsoft jet database engine could not find object ‘xyz.dbf’… Notice the dbf file extension. A dbf file name needs to be in 8.3 DOS name format. It is quite possible that some machines can open the file with a longer file name and others it must be in 8.3 DOS name format.
Now, isn’t that interesting? Long file names have been in existence since Windows 95, but yet the jet database engine doesn’t support them after almost 15 years!
By renaming the file to a DOS 8.3 format name resulted in a successful test on all systems. (Yes, the internal “short” name, the one with the ‘~’, also worked.) What is interesting is that one machine worked just fine with the long file name, but the rest didn’t. If anyone has any input in to why long names work on some systems and not others, I’d appreciate the input.
Recently I was tasked with implementing an automatic build and versioning system for our .NET development project. As part of that process, I needed to come up with a versioning mechanism to place into the process.
The system had to be automatic so that any member of the team could implement it as part of a regular build cycle. Other projects within the company integrate with this project, so distribution builds are a weekly occurrence.
The build environment has been kept simple: Visual Studio 2008 and Subversion. Integration between the two was accomplished by using the ankhsvn Visual Studio plugin. To enable Subversion maintenance from outside of Visual Studio, the TortoiseSVN Explorer shell extension is used.
Due to the numerous builds that occur, it is necessary to integrate a build number into the application version information. The AssemblyVersion and AssemblyFileVersion attributes allow for a four level versioning system. Having four levels would allow us to simply add the build number to the end of our existing standard three-level version system (Major.Minor.ServicePack).
The only issue was how to come up with a build number that would be meaningful. Visual Studio has an option to replace the third and fourth levels with values that are hacks of the date and time of the build. However, this option resulted in the removal of the Service Pack number from our version number, which was not acceptable.
Back in Visual Basic 6, there was a build option that auto-incremented the last value in the version each time the output was built. That feature was not available in the C/C++ versions of Visual Studio and was not brought forward to the .NET versions. Although an auto-incrementing value allows for determining which build is newer, it provides for not much else.
During my research, I came across a blog post where the author was utilizing the latest subversion revision as the build number. This allowed for a build to be directly connected to point in the subversion repository. However, this author’s instructions were utilizing MSBuild, which we were not.
The plan was to implement the following versioning scheme: Major.Minor.ServicePack.Build. The major, minor and service pack values would be specified manually and the build value would be generated automatically as part of the build process.
Coming up with the versioning scheme was only half of the work. The other half, and arguably the hardest half, was to come up with the actual implementation. The challenge was to determmine what tools would be needed to accomplish the task. The tools would have to be lightweight and easy to use.
I decided to utilize Windows PowerShell to accomplish the task. Not only could it be used for automating the build process, but it could also be used to perform automated tests on our .NET classes. PowerShell utilizes the .NET framework classes, so any task that we can accomplish in a .NET application could be accomplished in a PowerShell script.
To allow access to the Subversion repository, a command-line SVN client would be needed. I chose the SlikSVN client available from the Subversion client page. It comes with a Microsoft MSI installation package and was easily distributed to other team members.
Before diving into the PowerShell script, some work had to be done to make the job easier and more efficient. Each project has its own AssemblyInfo.cs file. Since our procedure would only update the build number, this would mean that each AssemblyInfo.cs file would have to be updated with the major, minor and service pack numbers. As the number of projects grows, this task becomes more prone to error.
To solve this issue, the AssemblyInfo.cs file would be split into two files. The first file, AssemblyVersionInfo.cs, would contain the company, product, copyright and version information. The second, AssemblyInfo.cs, would contain the remaining attributes. AssemblyVersionInfo.cs would be a single file that would be shared by all projects, whereas AssemblyInfo.cs would be located in each project’s directory.
By placing all version information into a single file, this reduces the modifications needed by the development team when a version changes. It also allows the PowerShell script to simply modify a single file rather than having to search through each project directory.
The first step in the process is to obtain the value of the latest Subversion revision. Alejandro Espinoza wrote a little PowerShell script that accomplished this task. With a bit of simplification for my use, here’s the result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function GetLatestRevisionNumber() { $revLinePattern = "(.*?)(Revision: )(\d+\.?\d*)(.*?)"; $result = svn info . $revision = 0; if([regex]::Match($result, $revLinePattern)) { $matches = [regex]::Split($result,$revLinePattern); $revision = $matches[3]; } return [int]$revision; } |
This PowerShell function calls ‘svn info’ to get the Subversion repository information for the current directory. Then it locates the line with ‘Revision’, pulls out the value and returns it to the caller.
Now that the latest revision value is obtained, we need to take that value and update the AssemblyVersionInfo.cs file. However, there are two issues that need to be addressed when doing so:
To address issue #1, the script will need to compare the updated value with the value that exists in the file. The file will only be updated if the value has changed.
To address issue #2, the revision level obtained above will be incremented before writing it to the file. Otherwise, the file will be updated each time the script is run. By incrementing the value, the value written to the file will match the level when the file is copied back into the respository after the update.
The PowerShell script to perform the update is quite simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | function UpdateAssemblyVersion() { $currRevision = GetLatestRevisionNumber; $nextRevision = [int]$currRevision + 1; $versionPattern = '(?\d+)\.(?\d+)\.(?\d+)\.\d+'; $hasChanged = 0; $assemblyFileData = Get-Content Common\AssemblyVersionInfo.cs; for($line=0; $line -lt $assemblyFileData.Length; $line++) { $newLine = [regex]::Replace($assemblyFileData[$line], $versionPattern, "`${major}.`${minor}.`${sp}." + $currRevision); if($newLine.CompareTo($assemblyFileData[$line]) -ne 0) { $hasChanged = 1; $newLine = [regex]::Replace($assemblyFileData[$line], $versionPattern, "`${major}.`${minor}.`${sp}." + $nextRevision); $currRevision = $nextRevision; $assemblyFileData[$line] = $newLine; } } if($hasChanged -eq 1) { write-host "Updating AssemblyVersionInfo.cs to version " $nextRevision "."; Set-Content Common\AssemblyVersionInfo.cs $assemblyFileData; svn commit Common -m `"Version change for build.`" } } |
These PowerShell functions are simply two steps in the entire build automation process. When placed between a Subversion update and a Visual Studio compile, they provide an automated method for integrating meaningful build numbers into your .NET assemblies.

Light 