<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Matt Penner</title>
	<atom:link href="http://mattpenner.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://mattpenner.info</link>
	<description>All about Matt Penner - blog, work experience, project portfolio, skills, etc</description>
	<pubDate>Wed, 03 Dec 2008 21:02:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Commercial Reporting Framework Comparisons</title>
		<link>http://mattpenner.info/2008/12/03/commercial-reporting-framework-comparisons/</link>
		<comments>http://mattpenner.info/2008/12/03/commercial-reporting-framework-comparisons/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 21:02:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/12/03/commercial-reporting-framework-comparisons/</guid>
		<description><![CDATA[I was responding to a recent CodeProject forum question and my response got so long and detailed I just thought I’d blog it instead.
If you haven’t been by CodeProject check it out.&#160; It’s a great site with an incredible wealth of very useful information in the articles and forum communities.
Anyway, the topic in question was [...]]]></description>
			<content:encoded><![CDATA[<p>I was responding to a recent <a href="http://www.codeproject.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeproject.com');" target="_blank">CodeProject</a> forum question and my response got so long and detailed I just thought I’d blog it instead.</p>
<p>If you haven’t been by CodeProject check it out.&#160; It’s a great site with an incredible wealth of very useful information in the articles and forum communities.</p>
<p>Anyway, the topic in question was this:</p>
<p><a title="http://www.codeproject.com/Lounge.aspx?msg=2828212#xx2828212xx" href="http://www.codeproject.com/Lounge.aspx?msg=2828212#xx2828212xx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeproject.com');">http://www.codeproject.com/Lounge.aspx?msg=2828212#xx2828212xx</a></p>
<p>“I&#8217;ve been tasked with researching some alternatives to SQL Server Reporting Services and was wondering what experiences and recommendations anyone out there has? </p>
<p>I&#8217;ve also seen a couple of add-ons for reporting services, some of which look quite promising - has anyone got any experience of these? </p>
<p>PS Ideally not Crystal Reports - I had to use this in an old job and *hated* it!!”</p>
<p>&#160;</p>
<p>I’ve used various reporting frameworks as a developer and end user in various projects for the past 7 years.&#160; While I am not up on the extremely current (such as developing in CR XI or SSRS 2008 yet) I hope this information will prove useful.&#160; If you have any corrections or suggestions you would like to make please chime in!</p>
<p>As a side note my organization will be installing SQL 2008 (waiting for a couple of months now for our purchasing process to get the license through) and I’ll have a chance to really play with SSRS 2008.&#160; I’ll post an update at that time.</p>
<p>Another side note; this is strictly a comparison of reporting, not business intelligence.</p>
<p>Another side note (how many of these can I have? :)).&#160; There are some very good open source frameworks (such as <a href="http://jasperforge.org/plugins/project/project_home.php?group_id=102" onclick="javascript:pageTracker._trackPageview('/outbound/article/jasperforge.org');" target="_blank">Jasper</a> for Java) that I have not had the opportunity to use.&#160; Commercial products like those listed here are not the only alternative.&#160; Plus, as several users have stated in the forum, rolling your own may be well suited to your project if you have very customized requirements, have a small reporting needs or restrictions on funds or use of open source limit your options.</p>
<p>Now, on to the comparison!</p>
<p>In several projects over the last 7 years I&#8217;ve used <a href="http://www.businessobjects.com/product/catalog/crystalreports/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.businessobjects.com');" target="_blank">Crystal Reports</a> (v8.5 and some limited XI), <a href="http://www.datadynamics.com/Products/ProductOverview.aspx?Product=ARNET3" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.datadynamics.com');" target="_blank">Active Reports</a> (v3) and <a href="http://msdn.microsoft.com/en-us/library/ms159106.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');" target="_blank">SSRS</a> (v2005).&#160; All have their pros and cons, however, they are in completely different areas.&#160; Note that there are now newer versions of each product so I can&#8217;t speak for new features.&#160; These also were the base products.&#160; No 3rd party controls or such were used. </p>
<p><strong>Here&#8217;s my very brief summary:</strong>    <br />CR: Best designer and overall most professional output of static reports.    <br />AR: Best tool from a strictly development perspective and most friendly to integration.    <br />SSRS: Free, fairly decent but still an “early” product.</p>
<p>All three had their definite &quot;quirks&quot; (i.e. bugs, hacks, required massaging, etc). </p>
<p>Here&#8217;s my take in different areas:   <br /><strong>Report Design (manual):</strong>    <br />CR had the best designer I have seen.&#160; Incredibly easy to use and I could create very rich and professional looking reports in a matter of minutes.&#160; CR actually replaced my quick and dirty T-SQL result printouts when a supervisor asked for some quick numbers.&#160; I could do a very professional layout in 2 minutes ready for use in a meeting rather than the dry text print of a result screen. However, extreme dilligence must be placed on good design.&#160; It is very easy to scatter formatting and calculation code all over the place.&#160; It can quickly become a mess of spaghetti and make debugging a report almost impossible.&#160; If you exercise good design such as using base functions that are called by other functions, basing formatting of functions rather than inline code, using well documented code or good function/variable names then this can be mitigated.&#160; XI comes with a new function and formatting explorer that really made hunting for customizations very easy.&#160; This was a real “pain” in 8.5.</p>
<p>Active reports had no real designer other than a VB form like designer built into .Net.&#160; I believe they have upgraded this in newer versions.&#160; With AR I found that it was often easier (and more accurate) to edit the design in code.&#160; Definitely not a rapid report development tool. However, I did find that of the three this tended to produce the most accurate results since I could almost hand code it myself.&#160; As an example images were exactly where I placed them and with the exact right dimensions the first time.&#160; That being said getting a very professional looking report really depended on your code/design skills there wasn’t really any help from AR in this department.</p>
<p>SSRS&#8217;s designer leaves a lot to be desired.&#160; It is very rigid, has no real-time editing, and overall lacks a lot of the usability features of CR.&#160; I could design decent reports much faster than AR, but it was difficult (if even possible) to get the same professional output of CR.&#160; I believe this has been somewhat upgraded in 2008, but I&#8217;m not sure to what degree. </p>
<p><strong>Advanced Design (i.e. functions, custom code, etc):</strong></p>
<p>CR lets you create functions for almost any UI area of the report and this could be coded in a VBScript like syntax or their own.&#160; I say UI area because there really was no control over the various events or rendering loops.&#160; You could really only alter cell values, do running functions or change formatting.&#160; That being said in the 8.5 version not all UI elements could be customized on a granular level.&#160; For instance, you may be able to bold or hide something with a function but then couldn’t change the font or size. (Don’t quote me verbatim on this.&#160; It’s just a example and my memory may not be accurate as to the actual specific limitations)</p>
<p>AR is pretty much a wide open playground for developers.&#160; I love the amount of control you have.&#160; It is pretty much entirely built with integration from the ground up.&#160; Almost anything you’d ever want to customize you have full ability (and the .Net language) at your disposal.</p>
<p>SSRS is a love/hate situation.&#160; You can use custom code in three different ways.&#160; You can enter “expressions” almost anywhere you would want to manipulate data or formatting.&#160; This is all in a VB like syntax so C# developers may not like that.&#160; Plus, expressions are written in a single line so if you want do do anything other than simple manipulations or conditionals expressions won’t work.&#160; Another con with expressions is much like CR pre vXI days, it’s very easy to “lose” a function because there is no one explorer tool like in CR XI that shows you all the different expressions that are embedded into the report.</p>
<p>A step above expressions is code embedded in the document.&#160; Here you can create full fledged functions that are callable by the expressions, which is a preferred method if you are doing the same thing more than once.&#160; However, in v2005 the embedded code has no designer.&#160; It literally is a textbox with all the code at the same time.&#160; There is no syntax highlighting, no IntelliSense and no debugging.&#160; You simply run the report and if it doesn’t successfully execute you try and decipher the exceptions thrown.</p>
<p>Beyond that you can write your own code in C# (or whatever .Net language you choose), compile these into an assembly and then reference them in the report.&#160; This is great because you get the full robust quality of the CLR and Visual Studio to create your functions.&#160; However, this does slow down the development process as you’re now working in several different places and (at least with VS2005) each time you made a change to the assembly you had to close the reporting solution and re-open it for VS to reference the updated assembly dll.</p>
<p><strong>Report Design (dynamically generated (even partially) within code):</strong>    <br />Sometimes people want to be able to generate reports from scratch or even partially depending on the use of the application.&#160; For instance, if you have a billing department, you may have several different reporting requirements based on the type of bill, who the bill-to party is, etc.&#160; In this case you may have a base report template with a header and footer and on the fly add different “parts’ to generate the completed report.&#160; This would be beyond static reports but not ad-hoc in the sense that the user is creating their own report.&#160; I don’t really have experience in this area but I’ll state what I believe to be true.&#160; Feel free to correct me.</p>
<p>I don’t believe that CR has any ability to do this what-so-ever.&#160; Correct me if they have a new feature or product out by my experience is you either use a static report or a completely user-driven ad-hoc report.</p>
<p>I really don’t know if AR has this ability.&#160; The reports are ultimately stored in XML (I believe) and it’s completely development driven so I would almost assume you could do this.&#160; However, because the reports are really .Net objects you get full capability such as inheritance.&#160; In v2 we created a template “base” report that had a header and footer.&#160; Then we simply created several different static reports that were derived from the base report.&#160; Almost like a master page scenario in ASP.Net.&#160; The designer, however, didn’t show the master page elements and didn’t give any indication you were using a derived report class so you just had to remember things like not to make use of page headers or footers.&#160; In v3 they broke this ability.&#160; I created a support issue on their bug tracker but it hadn’t been resolved when the project was finished a couple of years ago.&#160; I’m sure they’ve fixed this in the current version.&#160; It was handy though!</p>
<p>The above solution is not quite the same as using sub-reports.&#160; With sub-reports you create the base reoprts and include any sub-reports.&#160; A sub-report may be reused several times.&#160; In the above solution I created the base report and used that several times, which you can’t do in the sub-report scenario. </p>
<p>SSRS is based on XML, so theoretically you can design a complete report in code at run-time, however, I&#8217;ve yet to hear of anyone doing this in a practical sense.&#160; </p>
<p><strong>Ad Hoc Report Design (for end users):</strong>    <br />CR: There was no ad-hoc ability in CR 8.5 other than putting an actual designer control in your windows forms app.&#160; If you were selling the app I believe there were licensing restrictions around this and often software vendors had to sell a fully licensed copy of CR with their product, adding another $500 to the bill just for the ad-hoc ability.&#160; Business Objects may have relaxed this in the later versions.</p>
<p>I have used the Business Objects InfoView XI R2 web based ad-hoc system as an end user.&#160; It may be just the way the vendor set it up but in my opinion this is a terrible interface.&#160; It is very clunky and constantly returns useless errors if a field no longer exists on a database, if a function is syntactically incorrect, etc.&#160; A very un-user friendly product for non-technical users. In this day and age with web-based designers from almost anything such as designing a scrapbook like <a href="http://www.shutterfly.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.shutterfly.com');" target="_blank">ShutterFly</a> or Google Maps mashups, BO’s interface is a far cry from a well designed UI.&#160; As a web developer myself I would have to state that this mostly is a lack of a good web 2.0 or Java development staff.&#160; They use Java applets.&#160; While Java applets (and UI in general) have gotten a bad rap there are some very good designs that show it is possible.&#160; There is no real fundamental difference between what an applet vs a full blown app can do regarding UI.&#160; If you have ever used <a href="http://www.jetbrains.com/idea/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jetbrains.com');" target="_blank">IntelliJ</a> (from <a href="http://www.jetbrains.com/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jetbrains.com');" target="_blank">JetBrains</a>, the makers of <a href="http://www.jetbrains.com/resharper/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jetbrains.com');" target="_blank">ReSharper</a>) or <a href="http://www.eclipse.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.eclipse.org');" target="_blank">Eclipse</a> (yes they fudge on their UI rendering and it’s not really Java that finally draws the screen) then you’ve seen some outstanding interfaces.&#160; I’ve seen some incredible Java applet games (even in 3D 7 years ago) if you think Applets <strong><em>are</em></strong> different.&#160; There’s no reason why BO couldn’t do the same if they had developers with the proper skills.</p>
<p>Active Reports also gives ad-hoc ability in the sense of putting a designer control in the Windows Forms app.&#160; however, unlike Business Objects there is no licensing fee to to this.&#160; This is largely one of the biggest draws to AR. As a developer you can purchase it and use it in all your apps without having to worry about licensing issues with your customers.</p>
<p>AR has no web designer, at least not as of v3.</p>
<p>SSRS: Comes with Report Builder.&#160; It is a fairly easy to use system but may be confusing the way they &quot;navigate&quot; relationships.&#160; All in all it&#8217;s probably the easiest ad-hoc system I&#8217;ve seen, however, v2005 offers only the most basic functionality.&#160; For instance you cannot conditionally format text.&#160; A very promising first release and I&#8217;m excited to see where they take this. </p>
<p>As a side note, while SSRS 2005 is free in the SQL Server Standard edition, they do leave some cool features for the Enterprise edition.&#160; For instance, SSRS can dynamically generate views of a table showing field values, aggregates for foreign-key relationships and links to foreign key tables.&#160; As an example, if you have a database of customers, orders, products, etc, you could view an order, navigate to the items, navigate to the base item, navigate to inventory, navigate to the invoices, navigate to the vendors, and on and on, without any development.&#160; If you wanted a customized view of a particular table you simply create it and reference it.&#160; Then SSRS will dynamically generate the table views as normal but use your definition when viewing that particular table.&#160; This is a great way to “drill-down” into an app quickly when you need to check on the data rather than diving into the Query Analyzer.&#160; But, alas, this is only offered in SQL Enterprise, &lt;sigh&gt;.</p>
<p><strong>UI Controls:</strong>    <br />CR has fairly decent UI controls.&#160; Lines, boxes and other shapes worked fairly well if you navigate around the rendering quirks (like page breaks through shapes, etc).&#160; Their charts were fairly decent but did not have near the granularity of something like Excel. </p>
<p>I didn’t use the AR controls on the projects we used it on so I can’t really speak to this.</p>
<p>SSRS has very basic user controls such as shapes, images and charts.&#160; I haven’t really used these other than the image control.&#160; It worked as expected.&#160; </p>
<p>I will say that the chart control had some definite quirks in Report Builder.&#160; When demonstrating RB to a group of co-workers we built a chart, viewed it, changed some formatting, viewed the changes, etc.&#160; We eventually got to a point where I asked it to chart an invalid sum or result.&#160; RB complained as expected, but we couldn’t simply change the values back to their valid settings.&#160; It somehow remembered and said “Nope.&#160; I don’t care what changes you make I’m not showing this chart again!”&#160; The only way to get rid of the error was to drop the chart all together and re-create it.</p>
<p>All three packages have 3rd party vendors who sell very nice UI controls.&#160; If your final intention is a very flexible and professional looking report you would probably want to explore these options.</p>
<p><strong>Developer Take:</strong></p>
<p>This is just a small section on how it is to develop with these various reoprting tools.</p>
<p>CR (as of v8.5) has almost no real report manipulation beyond their built-in functions.&#160; As a developer you can change various run-time things such as page setup, the target database, etc but the actual report must be pre-built.</p>
<p>AR is a developer’s dream!&#160; It is entirely created for .Net.&#160; You have full access to the reporting life-cycle.&#160; Just as you have access to events for web forms or ASP.Net web pages like Init, Dispose, etc you have the same abilities with AR.&#160; You can run code during the report init phase, the before or after retrieving a record from the db, before or after rendering a page, etc.&#160; Anything you want to do you can do.&#160; It’s definitely a breath of fresh air for any developer.</p>
<p>SSRS really has no other abilities than what was talked about above in the Advanced section.&#160; Like CR you can change a couple of run-time settings but you don’t have near the control of AR.&#160; Again, I suppose you could intercept the xml and manipulated it on the fly before passing it to the rendering engine, but again, you have no control other than basic formatting/calculation functions while in the actual generation process.</p>
<p><strong>Distribution: </strong></p>
<p>I’ve used four basic ways to distribute my reports: give the report file to the user, embed it in my Windows Forms app, embed it into my web app or upload it to some Reporting Server.</p>
<ol>
<li>Give the report to the user(s).&#160; With the web this is becoming less and less of a desired option.     <br />CR: The user must have either the full CR product or a report viewer.      <br />AR: I don’t think this is an option at all.      <br />SSRS: With Report Builder you can export the report as an xml file, which you can share with co-workers or give to a developer who can use it as a base in SSRS to expand on the functionality.&#160; Comes in handy when an end user designs a report the way they want in RB but then requires some more advanced functionality so they give it to the developer to make the changes and deploy on the Report Server.&#160; This gives some freedom to the end user while taking some of the labor off the developer.</li>
<li>Embed it into the Windows Forms app.&#160; All three products can do this and usually without any problem what-so-ever.&#160; Since most of the security restrictions have been removed by running it in an application and the referenced reports/dlls are always available this is relatively straight forward.&#160; In all three cases a “report viewer” control will be embedded in the app.&#160; There is no licensing restrictions with using the report viewer with any of the there companies.</li>
<li>Embed it into the web app:     <br />I haven’t done this with CR but I know they have web controls for this.      <br />With AR you can render the app in a variety of different ways.&#160; I especially like that I can, in code, render the report in a variety of formats, such as pdf, and stream it to the user as a download.      <br />SSRS has a web viewer control but its very problematic.&#160; For instance parameters for linked reports or sub-reports don’t seem to carry through well.&#160; Dynamically assigning parameters is a head ache all together.&#160; On one app where we use forms authentication we simply unlinked the reports and created separate urls.&#160; Really lost a lot of nice dynamic functionality when we did that but it was the only we could find to adequately give data to only the users who should be able to view it.</li>
<li>Reporting Server:     <br />As of v8.5 BO had a wonderful Crystal Reports Server web based server.&#160; It was very easy to use and was free if you only needed 5 concurrent users.&#160; This worked great for small departments.&#160; We had a reporting server crash and rebuilding the settings from backup was a pain.&#160; It took about a day and could have been made much easier but all in all the server was a pleasure to use when it was up and running.&#160; It offered all the normal functions such as deploying reports, distributing them via on demand, sending to email, caching, scheduling, etc.&#160; It even served as more of a document server in that it would let you upload other documents like PDFs, Word docs, etc.&#160; <br />Read the quirk below regarding the ActiveX report viewer control.&#160; It was the only sore point of the system.&#160; Unfortunately BO changed the licensing and now you can only use it for free with 5 <strong><em>named</em></strong> users.&#160; Now its really only good as a test server or a very very small department.&#160; To buy it is several thousands of dollars which makes it prohibitive for some groups and not really worth the money.&#160; A good development team could recreate the web app if they really wanted to use CR reports.      <br />AR has no server.      <br />SSRS has their Reporting Server.&#160; This is also an excellent system.&#160; It mirrors much of the functionality of the CR server (except that it only serves SSRS documents).&#160; This also is a pleasure to use and is very easy to implement.&#160; In 2008 they have revamped the server and now it no longer depends on IIS.&#160; </li>
</ol>
<p><strong>Quirks:</strong></p>
<p>This is just all around quirks.&#160; There are a multitude for each app and you’ll just have to learn how to work around each one.&#160; Here are just a few I can remember off the top of my head.</p>
<p>CR:</p>
<ul>
<li>As of version 8.5 the browser web control used by CR Server (the web server) was a real pain.&#160; It was an ActiveX object and often would become corrupt or not download properly.&#160; Also, BO would regularly release new versions of the control and only half the browsers would correctly download the new version.&#160; The only way to manually re-install the control was to log in as an administrator (we had IE locked down fairly tight at that company), go into IE, view the downloaded objects and manually remove the control.&#160; Then we had to see if IE would correctly download the control the next time, which was up to chance again.</li>
<li>Using the API in v8.5 for web forms was somewhat problematic.&#160; Not all reporting capabilities that were available in the designer were available in the API.&#160; Also, sometimes the order or inclusion of specific calls determined the output.&#160; For instance, you could not change some of the page setup settings without first telling it what size of paper you wanted.&#160; If the report was built for 8.5&#215;11 (Letter) and I didn’t specifically state that in code none of my settings would be applied.&#160; If I applied all my settings and then set it for Letter it would wipe out all my previous settings.&#160; </li>
</ul>
<p>AR:</p>
<ul>
<li>Again, as of version 3 they broke report inheritance.&#160; I’m sure it’s fixed by now, but what troubled me is they broke it from v2 to v3 and never fixed it for several months.&#160; This force our project at the time to go back and use v2.&#160; this could be quite a problem if you had already developed several reports in v3 and now had to run v2 and v3 on the same computer (which was a headache in itself).</li>
</ul>
<p>SSRS:</p>
<ul>
<li>The web report viewer control doesn’t use standard printing functionality.&#160; They rely on their own control.&#160; This is a large hassle because in many large organizations they don’t let their users download and install software on their machines.&#160; This causes a very obscure error to appear on the screen causing help desk calls (usually to me).&#160; The only thing we can do is train users to export the report as PDF and print it through Acrobat Reader.</li>
</ul>
<p>&#160;</p>
<p>Anyway, that’s my take.&#160; While some of these products are older the general sentiment is still the same.&#160; CR has the best designer, AR is the best for developer integration, and SSRS is free and coming along.</p>
<p>I’ll try and post an update once I’ve had a chance to use SSRS 2008.</p>
<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4c731825-0b4e-4de8-a5f0-980c04ee5cfa" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/reporting" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">reporting</a>,<a href="http://technorati.com/tags/Crystal+Reports" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Crystal Reports</a>,<a href="http://technorati.com/tags/Active+Reports" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Active Reports</a>,<a href="http://technorati.com/tags/SSRS" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">SSRS</a>,<a href="http://technorati.com/tags/SQL+Server+Reporting+Services" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">SQL Server Reporting Services</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/12/03/commercial-reporting-framework-comparisons/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting things done &#8211; Sometimes simpler is better</title>
		<link>http://mattpenner.info/2008/12/01/getting-things-done-sometimes-simpler-is-better/</link>
		<comments>http://mattpenner.info/2008/12/01/getting-things-done-sometimes-simpler-is-better/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 19:26:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/12/01/getting-things-done-sometimes-simpler-is-better/</guid>
		<description><![CDATA[I’m working on a new project for my work.  I’m using S#arp Architecture started by Billy McCafferty, which is a framework using ASP.Net MVC, NHibernate for database persistence and Ninject for dependency injection.  It’s really shaping up to be a great framework and I’m learning a lot.
With NHibernate, you often come to the point where [...]]]></description>
			<content:encoded><![CDATA[<p>I’m working on a new project for my work.  I’m using <a href="http://code.google.com/p/sharp-architecture/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');" target="_blank">S#arp Architecture</a> started by Billy McCafferty, which is a framework using ASP.Net MVC, <a href="http://www.hibernate.org/343.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hibernate.org');" target="_blank">NHibernate</a> for database persistence and <a href="http://ninject.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/ninject.org');" target="_blank">Ninject</a> for dependency injection.  It’s really shaping up to be a great framework and I’m learning a lot.</p>
<p>With NHibernate, you often come to the point where you have to map subclasses to your database.  The two prevailing strategies are one table per class or one table per class hierarchy.  You can look up any several dozen documents on these strategies.  For my project I chose one table per class hierarchy for one of my classes and its subclasses.</p>
<p>If you’re not familiar with Hibernate mapping documents, if you have one table per class hierarchy you have a single table storing the parent class and any subclasses all together.  This has its advantages, however, you have to have a column in the table (the discriminator) which holds a value telling Hibernate which class this record belongs to.  For instance, if I have a parent class of Person with two subclasses of Employee and Client, my discriminator field may hold “P” for Person, “E” for employee and “C” for client.</p>
<p>S#arp Architecture makes use of <a href="http://code.google.com/p/fluent-nhibernate/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');" target="_blank">Fluent Nhibernate</a>, which allows you to create Hibernate mapping documents in code in a fluent style.  Very nice.  It makes full use of generics and has been a pleasure to use once I dusted off my knowledge of mapping documents.</p>
<p>The problem is Fluent has a bug where it puts in discriminator elements for the subclasses.  There should only be one element describing the discriminator field and that goes in the main class definition.  For some reason Fluent also puts it in the subclass definitions causing Hibernate to throw an error.</p>
<p>So, what do you do?  Well, the great thing about open source is you can open up the code and find the problem.  I did just that but I hit another snag.  I love using Generics in my code, however, I’m not experienced at all at creating classes that use them.  After spending about a half an hour to find the problem and think about how to solve it I realized I didn’t have time to refactor the bug and relevant pieces to a logical usage.</p>
<p>So, I did the next best thing.  I added two lines of code to remove the element during the generation and fixed the issue.</p>
<p>The code to generate and return the mapping in xml ends with this:</p>
<pre>
1: writeTheParts(classElement, visitor);
2: return document;
</pre>
<p>So, I added the following:</p>
<pre>
1: writeTheParts(classElement, visitor);
2: foreach (XmlNode discriminator in document.SelectNodes("//subclass/discriminator"))
3:   discriminator.ParentNode.RemoveChild(discriminator);
4: return document;
</pre>
<p>In the code above, document is an XmlDocument type.  I used an XPath expression to find all the subclass elements that had a child discriminator element and then removed them.  The nice thing is this doesn’t affect any code that doesn’t have the bug.  It’s fairly clean and doesn’t get in the way at all.</p>
<p>While this certainly isn’t a true fix it does solve the problem in a very orderly and understandable way.  I still think it’s a hack but it helped me get back to my project.  I did submit the test (always create a test first!) and the patch to the project incase they wanted to fix the bug.  I also suggested that it still be refactored correctly by someone who is a little more experienced with Generics and the project.</p>
<p>So, in a case like this, I’d advocate simple when the solution is fairly clean, does exactly what it is supposed to do and there may not be time (or experience) for the alternative.</p>
<div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ef345e73-1c07-4c31-8fd4-15cf28f993a6" class="wlWriterEditableSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/NHibernate" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">NHibernate</a>,<a rel="tag" href="http://technorati.com/tags/Ninject" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">Ninject</a>,<a rel="tag" href="http://technorati.com/tags/Fluent" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">Fluent</a>,<a rel="tag" href="http://technorati.com/tags/Patch" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">Patch</a>,<a rel="tag" href="http://technorati.com/tags/TDD" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">TDD</a>,<a rel="tag" href="http://technorati.com/tags/XmlDocument" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">XmlDocument</a>,<a rel="tag" href="http://technorati.com/tags/XPath" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">XPath</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/12/01/getting-things-done-sometimes-simpler-is-better/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Importance of Proper Date Calculations</title>
		<link>http://mattpenner.info/2008/11/14/the-importance-of-proper-date-calculations/</link>
		<comments>http://mattpenner.info/2008/11/14/the-importance-of-proper-date-calculations/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 17:34:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/11/14/the-importance-of-proper-date-calculations/</guid>
		<description><![CDATA[There are a million blog posts on this sort of thing but it just bit us so I thought I&#8217;d add mine to the mix.
Date calculations can be notoriously difficult depending on the language you are using.&#160; However, DO NOT succumb to the desire to &#34;fake&#34; it as our vendor did.&#160; Here&#8217;s what happened:
In California [...]]]></description>
			<content:encoded><![CDATA[<p>There are a million blog posts on this sort of thing but it just bit us so I thought I&#8217;d add mine to the mix.</p>
<p>Date calculations can be notoriously difficult depending on the language you are using.&#160; However, DO NOT succumb to the desire to &quot;fake&quot; it as our vendor did.&#160; Here&#8217;s what happened:</p>
<p>In California every school has to submit data for their special ed students/programs to receive proper funding.&#160; This is called a CASEMIS report, and reporting day is every June 30th and December 1st.</p>
<p>For CASEMIS if a child is under 6 they are in one category and if 6 and over in another. </p>
<p>In our data there is one student in question who&#8217;s date of birth is 12/3/2002.&#160; So on the reporting date of 12/1/2008 this student will be just two days shy of 6 years old. </p>
<p>We were getting an error in our validation process because apparently our vendor was calculating ages using 1 year = 365 days.&#160; 12/1/2008 &#8211; 12/3/2002 yields 2190 days, which at 365 days a year results in 6 years exactly. </p>
<p>Ugh!&#160; Sorry, but the &quot;close enough for government work&quot; doesn&#8217;t apply here.</p>
<p>I don&#8217;t know exactly what language they are using but I believe they use perl on the back end and Business Objects InfoView XI for the reporting.&#160; The actual date calculation could be in either of these two places, or somewhere entirely different.</p>
<p>While some languages make calculating proper dates difficult, there is almost always a correct way to do it.</p>
<p>For instance, in Microsoft T-SQL, asking the difference in years between 12/1/2008 and 12/3/2002 using:   <br />SELECT DateDiff(yy, &#8216;12/3/2002&#8242;, &#8216;12/1/2008&#8242;)    <br />incorrectly returns 6 years, since 2008 &#8211; 2002 = 6. </p>
<p>However, if you change the question slightly and ask if the birthdate + 6 years is less than the reporting date using:   <br />SELECT CASE WHEN DateAdd(yy, 6, &#8216;12/3/2002&#8242;) &lt; &#8216;12/1/2008&#8242; THEN &#8216;6 or Over&#8217; ELSE &#8216;Under 6&#8242; END    <br />this results in the correct response &#8220;Under 6&#8221;. </p>
<p>It&#8217;s a matter of finding the proper question and syntax for the language.</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:90f4ec0e-754c-4be1-beff-89490caa73a1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Date%20Calculation" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Date Calculation</a>,<a href="http://technorati.com/tags/SQL" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">SQL</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/11/14/the-importance-of-proper-date-calculations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Unit Testing HtmlHelpers</title>
		<link>http://mattpenner.info/2008/11/13/unit-testing-htmlhelpers/</link>
		<comments>http://mattpenner.info/2008/11/13/unit-testing-htmlhelpers/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 00:02:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/11/13/unit-testing-htmlhelpers/</guid>
		<description><![CDATA[I have a pretty decent project at my work that I am using ASP.Net MVC for.  It is a great framework and it&#8217;s my first real development project in a long time so I&#8217;m pretty excited.
I&#8217;m really stealing myself to use TDD, with very heavy emphasis on the first D, &#8220;Driven&#8221;.  I&#8217;m not allowing myself [...]]]></description>
			<content:encoded><![CDATA[<p>I have a pretty decent project at my work that I am using <a href="http://www.asp.net/mvc" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');" target="_blank">ASP.Net MVC</a> for.  It is a great framework and it&#8217;s my first real development project in a long time so I&#8217;m pretty excited.</p>
<p>I&#8217;m really stealing myself to use TDD, with very heavy emphasis on the first D, &#8220;Driven&#8221;.  I&#8217;m not allowing myself to write a line of code without a test first.  It&#8217;s a little hard because IntelliSense is pretty meaningless in tests if the actual objects haven&#8217;t even been built.  When things get a little muddy I go and create a quick empty controller or something before I finish the actual test.  This is just so that I can let VS 2008 and <a href="http://www.jetbrains.com/resharper/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jetbrains.com');" target="_blank">ReSharper</a> work their magic adding namespaces and proper syntax.</p>
<p>Anyway, before I get into the nitty gritty I wrote this post because I was on a search of how to unit test my custom <a href="http://www.asp.net/learn/mvc/tutorial-09-cs.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');" target="_blank">HtmlHelpers</a>.  I found some decent posts and looked at the source for MvcContrib, but I didn&#8217;t need anything fancy.  I&#8217;m just creating a file input tag. I don&#8217;t need to mock the Context or anything.  I didn&#8217;t find a easy post anywhere on how to do this.  It turns out if you don&#8217;t need anything special it&#8217;s quite easy indeed.  If you&#8217;re looking for this then read on.</p>
<p>Anyway, I have a form where the user will upload a couple of files.  Using Scott Hanselman&#8217;s <a href="http://www.hanselman.com/blog/ABackToBasicsCaseStudyImplementingHTTPFileUploadWithASPNETMVCIncludingTestsAndMocks.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hanselman.com');" target="_blank">great blog post</a> on unit testing uploading files using MVC I have a controller that now requires two non-empty files before it returns a success view.</p>
<p>I&#8217;ll flesh that out a little more with some actual validation of the upload contents but for now I&#8217;m refactoring my initial form.</p>
<p>From Scott&#8217;s post what I began with is the following:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/SELPA/ReceiveCASEMISTables&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span> <span style="color: #000066;">enctype</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;multipart/form-data&quot;</span>&gt;</span>    
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableA&quot;</span>&gt;</span>Table A:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>    
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableA&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableA&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>    
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">label</span> <span style="color: #000066;">for</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableB&quot;</span>&gt;</span>Table B:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">label</span>&gt;</span>    
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableB&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableB&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>    
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Submit&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span></pre></div></div>

<p>This doesn&#8217;t make any use of HtmlHelpers so I wanted to refactor this.  There is no FileInput HtmlHelper but you could easily use the Textbox extension as in the following:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp csharp" style="font-family:monospace;"><span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">TextBox</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tableA&quot;</span>, <span style="color: #0600FF;">null</span>, <span style="color: #008000;">new</span> <span style="color: #000000;">&#123;</span> enctype <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;multipart/form-data&quot;</span> <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span></pre></div></div>

<p>And this would product the following correct HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;file&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableA&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;tableA&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>There are two things about this that bug me however.  First and foremost, did I save any effort?  The HtmlHelper code is <strong><em>actually longer </em></strong>then the straight HTML itself!  In my opinion HtmlHelpers should help in some way, not just be used because they are there.  So, if it doesn&#8217;t save me any extra work or protect me from something such as malformed urls or localization formatting, then there&#8217;s no point.  Second is that blank value attribute.  Why do I need that?</p>
<p>So, being the developer that I am, I thought I&#8217;d create my own HtmlHelper for a File Input textbox.  Using TDD this requires that I write my test first:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp csharp" style="font-family:monospace;"><span style="color: #0600FF;">namespace</span> Tests.<span style="color: #0000FF;">CECWA</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Helpers</span><span style="color: #000000;">&#123;</span>
  <span style="color: #000000;">&#91;</span>TestFixture<span style="color: #000000;">&#93;</span>
  <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> FileInputExtensionsTests
  <span style="color: #000000;">&#123;</span>
    <span style="color: #000000;">&#91;</span>Test<span style="color: #000000;">&#93;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> CanGetCorrectOutput<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
      <span style="color: #FF0000;">string</span> html <span style="color: #008000;">=</span> FileInputExtensions.<span style="color: #0000FF;">FileInput</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">null</span>, <span style="color: #666666;">&quot;testName&quot;</span><span style="color: #000000;">&#41;</span>;
      <span style="color: #0600FF;">const</span> <span style="color: #FF0000;">string</span> expected <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;&lt;input type=<span style="color: #008080; font-weight: bold;">\&quot;</span>file<span style="color: #008080; font-weight: bold;">\&quot;</span> name=<span style="color: #008080; font-weight: bold;">\&quot;</span>testName<span style="color: #008080; font-weight: bold;">\&quot;</span> id=<span style="color: #008080; font-weight: bold;">\&quot;</span>testName<span style="color: #008080; font-weight: bold;">\&quot;</span> /&gt;&quot;</span>;
      Assert.<span style="color: #0000FF;">That</span><span style="color: #000000;">&#40;</span>html, <span style="color: #008000;">Is</span>.<span style="color: #0000FF;">EqualTo</span><span style="color: #000000;">&#40;</span>expected<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #000000;">&#125;</span> 
  <span style="color: #000000;">&#125;</span> 
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>I use <a href="http://www.nunit.org/index.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.nunit.org');" target="_blank">NUnit</a> but it&#8217;s pretty similar in any testing framework.  FileInputExtensions is my extension class containing my custom HtmlHelper FileInput.  The null parameter is the HtmlHelper class that is actually extended.  Since I&#8217;m not making use of the Context or anything else I can simply pass a null in.  If I were doing something fancy such as needing the base path of the app then I&#8217;d have to mock this out like the other more extensive posts do.</p>
<p>This test simply calls my extension method and stores the result in the html variable.  I store what I expect in my expected variable.  Then I assert that they are equal.  Quite easy actually.</p>
<p>When I build my project it of course doesn&#8217;t compile since there is no FileInputExtensions class.  So I do the bare minimum to compile:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp csharp" style="font-family:monospace;"><span style="color: #0600FF;">namespace</span> CECWA.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Helpers</span>
<span style="color: #000000;">&#123;</span>    
  <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">class</span> FileInputExtensions    
  <span style="color: #000000;">&#123;</span>        
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">string</span> FileInput<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span> HtmlHelper helper, <span style="color: #FF0000;">string</span> name<span style="color: #000000;">&#41;</span>        
    <span style="color: #000000;">&#123;</span>            
      <span style="color: #0600FF;">throw</span> <span style="color: #008000;">new</span> NotImplementedException<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;        
    <span style="color: #000000;">&#125;</span>    
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Everything now compiles but my test fails.  So, lets complete the method:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">string</span> FileInput<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span> HtmlHelper helper, <span style="color: #FF0000;">string</span> name<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;&lt;input type=<span style="color: #008080; font-weight: bold;">\&quot;</span>file<span style="color: #008080; font-weight: bold;">\&quot;</span> name=<span style="color: #008080; font-weight: bold;">\&quot;</span>{0}<span style="color: #008080; font-weight: bold;">\&quot;</span> id=<span style="color: #008080; font-weight: bold;">\&quot;</span>{0}<span style="color: #008080; font-weight: bold;">\&quot;</span> /&gt;&quot;</span>, name<span style="color: #000000;">&#41;</span>; 
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>All set.  My test passes and now I&#8217;ve got an extension method all ready to use.</p>
<p>After creating another test and extension method for a Label element I have now refactored my View above to the following:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp csharp" style="font-family:monospace;"><span style="color: #008000;">&lt;%</span> Html.<span style="color: #0000FF;">BeginForm</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;ReceiveCASEMISTables&quot;</span>, <span style="color: #666666;">&quot;SELPA&quot;</span>, FormMethod.<span style="color: #0000FF;">Post</span>, <span style="color: #008000;">new</span> <span style="color: #000000;">&#123;</span>enctype <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;multipart/form-data&quot;</span><span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span>; <span style="color: #008000;">%&gt;</span>
  <span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">Label</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tableA&quot;</span>, <span style="color: #666666;">&quot;Table A Filename:&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span>
  <span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">FileInput</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tableA&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span> <span style="color: #008000;">&lt;</span>br <span style="color: #008000;">/&gt;</span>
  <span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">Label</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tableB&quot;</span>, <span style="color: #666666;">&quot;Table B Filename:&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span>
  <span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">FileInput</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;tableB&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span> <span style="color: #008000;">&lt;</span>br <span style="color: #008000;">/&gt;</span>
  <span style="color: #008000;">&lt;%=</span> Html.<span style="color: #0000FF;">FormHelper</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Submit</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Upload Files&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">%&gt;</span>
<span style="color: #008000;">&lt;%</span> Html.<span style="color: #0000FF;">EndForm</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #008000;">%&gt;</span></pre></div></div>

<p>OK, if you compare the pure HTML version and this one you don&#8217;t see much difference in the &#8220;effort&#8221;.  However, this is more protected against improper paths in my form action url, typos in my various field ID&#8217;s, and just general lousy HTML coding in general.</p>
<p>Multiply this over several dozen pages and you start to feel a real tight management on your html output and maintainability.  For instance, if I want to change the way my FileInput extension renders I simply update my test, update my class to pass and now every place a FileInput helper is used has been updated through out the site.  Nice!</p>
<div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f65df56f-2c61-4ec1-9c8e-23fd8b22705b" class="wlWriterSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/HtmlHelper" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">HtmlHelper</a>,<a rel="tag" href="http://technorati.com/tags/TDD" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');">TDD</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/11/13/unit-testing-htmlhelpers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Microsoft Surface: SecondLight</title>
		<link>http://mattpenner.info/2008/10/30/microsoft-surface-secondlight/</link>
		<comments>http://mattpenner.info/2008/10/30/microsoft-surface-secondlight/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 16:03:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[Fun]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/10/30/microsoft-surface-secondlight/</guid>
		<description><![CDATA[If you know anything about Microsoft Surface than this will probably peek your interest.&#160; Things like this may just be eye candy for now, but you can see in just a matter of years (or less) the way we interact with computers in our daily lives will be drastically different. 
I don&#8217;t mean the way [...]]]></description>
			<content:encoded><![CDATA[<p>If you know anything about <a href="http://www.microsoft.com/surface" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.microsoft.com');" target="_blank">Microsoft Surface</a> than this will probably peek your interest.&#160; Things like this may just be eye candy for now, but you can see in just a matter of years (or less) the way we interact with computers in our daily lives will be drastically different. </p>
<p>I don&#8217;t mean the way we all normally use computers, but how we do <strong><em>everything else</em></strong>.&#160; Look at the way people are using phones now.&#160; They play games, text around the world, get driving directions, take videos and pictures, listen to music and a whole host of other things we never though of 5 years ago.&#160; If you went back to just the year 2000 and told everyone what phones would be like today most would never believe you.</p>
<p>That&#8217;s where Surface and technologies like it are taking us.&#160; When you&#8217;re out and about you&#8217;ll be interacting with display technology like this every where.&#160; Whether it&#8217;s ordering off a menu at a restaurant, getting plane tickets, adjusting your hotel amenities and upgrading your rental car all during your layover at the airport, finding where stores are and what sales they have at a mall display, etc information will be much richer and more interactive than we have now.</p>
<p>OK, get the point.&#160; <img src='http://mattpenner.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>SecondLight is a technology where a second image is literally projected through the first.&#160; It isn&#8217;t visible until a translucent item is placed in front of it.&#160; This could be something as simple as a sheet of tracing paper.</p>
<p>that isn&#8217;t so special in itself, this easily could have been simulated with the older Surface technology.&#160; It&#8217;s the fact that this second image is <strong><em>projected</em> </strong>that really beefs things up.&#160; Suddenly displays are becoming more &quot;3D&quot;.&#160; Not in the traditional sense but you can hold the paper above the surface for an easier view.&#160; They showed some plexiglass &quot;disks&quot; that were molded with a prism inside.&#160; This allowed the light to bend and display the image on the side.&#160; It&#8217;s all simply amazing.</p>
<p>Check out this article and watch the video.&#160; It&#8217;s just mind blowing.</p>
<p><a title="http://www.pcpro.co.uk/news/233511/secondlight-surface-on-steroids.html" href="http://www.pcpro.co.uk/news/233511/secondlight-surface-on-steroids.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.pcpro.co.uk');">http://www.pcpro.co.uk/news/233511/secondlight-surface-on-steroids.html</a></p>
<p>As I always say, this is an amazing time to be alive.</p>
<p>Take care all!</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e2e8da81-48cc-4cb9-bc06-687e76f403e1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Microsoft%20Surface" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Microsoft Surface</a>,<a href="http://technorati.com/tags/SecondLight" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">SecondLight</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/10/30/microsoft-surface-secondlight/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The anatomy of the first video game</title>
		<link>http://mattpenner.info/2008/10/24/the-anatomy-of-the-first-video-game/</link>
		<comments>http://mattpenner.info/2008/10/24/the-anatomy-of-the-first-video-game/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 16:11:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[Fun]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/10/24/the-anatomy-of-the-first-video-game/</guid>
		<description><![CDATA[
http://www.msnbc.msn.com/id/27328345/
&#160;
This was a pretty fun read.&#160; The only oscilloscopes I&#8217;ve ever used was during my physics class in high school (we weren&#8217;t allowed to touch it) and during my engineering labs at Cal Poly.&#160; It&#8217;s fun to see something like this.&#160; Check out the video towards the middle if you want to see it in [...]]]></description>
			<content:encoded><![CDATA[</p>
<p><a title="http://www.msnbc.msn.com/id/27328345/" href="http://www.msnbc.msn.com/id/27328345/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.msnbc.msn.com');">http://www.msnbc.msn.com/id/27328345/</a></p>
<p>&#160;</p>
<p>This was a pretty fun read.&#160; The only oscilloscopes I&#8217;ve ever used was during my physics class in high school (we weren&#8217;t allowed to touch it) and during my engineering labs at Cal Poly.&#160; It&#8217;s fun to see something like this.&#160; Check out the video towards the middle if you want to see it in action. </p>
<p> <img src='http://mattpenner.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/10/24/the-anatomy-of-the-first-video-game/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Microsoft to include jQuery in Visual Studio</title>
		<link>http://mattpenner.info/2008/10/17/microsoft-to-include-jquery-in-visual-studio/</link>
		<comments>http://mattpenner.info/2008/10/17/microsoft-to-include-jquery-in-visual-studio/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 20:12:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[jQuery]]></category>

		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://mattpenner.info/?p=43</guid>
		<description><![CDATA[This is absolutely amazing.  If you&#8217;ve never used jQuery definitely check it out.  Ever since James Johnson (president of the Inland Empire .Net User&#8217;s Group) did a presentation on it last year I&#8217;ve been hooked.  It&#8217;s is an outstanding JavaScript framework that actuallly makes JavaScript a pleasure to use.
As a classically trained developer I&#8217;ve always [...]]]></description>
			<content:encoded><![CDATA[<p>This is absolutely amazing.  If you&#8217;ve never used <a href="http://jquery.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/jquery.com');" target="_blank">jQuery </a>definitely check it out.  Ever since <a href="http://www.duringlunch.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.duringlunch.com');" target="_blank">James Johnson</a> (president of the <a href="http://www.iedotnetug.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.iedotnetug.org');" target="_blank">Inland Empire .Net User&#8217;s Group</a>) did a presentation on it last year I&#8217;ve been hooked.  It&#8217;s is an outstanding JavaScript framework that actuallly makes JavaScript a pleasure to use.</p>
<p>As a classically trained developer I&#8217;ve always approached JavaScript as a tool to use only when absolutely necessary and as a last resort.  Dealing with cross browser compatibility and just plain frustration over the language has made JavaScript a tool of evil in my development toolbelt.</p>
<p>With jQuery I not only now consider JavaScript a valuable asset I actually love to develop in it.</p>
<p>Hearing that Microsoft is now including it in their IDE is pretty exciting.  This means that IntelliSense and debugging (while possible with some great workarounds from the jQuery community) will most likely eventually be fully supported for jQuery.  I&#8217;ve worked with lots of development environments and Visual Studio is by far one of the best IDE&#8217;s around.</p>
<p>Probably even more exciting is that this furthers the strategy that MS is really interested in working with developers.  Some of my friends are probably tired of me bashing the old-school &#8220;Microsoft Way&#8221;.  Seeing the real encouragement of MS through employees like <a href="http://weblogs.asp.net/Scottgu/" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">Scott Gu</a>, <a href="http://haacked.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/haacked.com');" target="_blank">Phil Haack</a> and others on projects like <a href="http://www.asp.net/mvc" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');" target="_blank">MVC </a>and such really make it apparent that MS is offering alternatives for developers who want the ability to code using modern standards.</p>
<p>Actually integrating jQuery into Visual Studio shows that MS is willing to offer alternatives to their own prodcuts such as the ASP.Net AJAX JavaScript framework.  MS is no longer in the &#8220;We&#8217;re Microsoft.  Our way or the highway&#8221; mentality.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/10/17/microsoft-to-include-jquery-in-visual-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SQL Data Auditing</title>
		<link>http://mattpenner.info/2008/10/08/sql-data-auditing/</link>
		<comments>http://mattpenner.info/2008/10/08/sql-data-auditing/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 16:25:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/10/08/sql-data-auditing/</guid>
		<description><![CDATA[In an ideal world you would design your applications so that your users could never enter bad data.&#160; Well, that&#8217;s not always possible for some technical reasons and for 3rd party apps you&#8217;re at the mercy of the vendor.
&#160;
One case in point is our Student Information System (SIS) at the Val Verde Unified School District.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>In an ideal world you would design your applications so that your users could never enter bad data.&nbsp; Well, that&#8217;s not always possible for some technical reasons and for 3rd party apps you&#8217;re at the mercy of the vendor.</p>
<p>&nbsp;</p>
<p>One case in point is our Student Information System (SIS) at the Val Verde Unified School District.&nbsp; It does a great job and we love it, but as a developer it does have its cons.&nbsp; The database isn&#8217;t as normalized as I would prefer and sometimes their data model just seems weird.&nbsp; Granted it is a Microsoft Access UI that links to a SQL back end, however, it still doesn&#8217;t change the way things are.</p>
<p>&nbsp;</p>
<p>In this case we need to perform audits on our data.&nbsp; Anyone who is in data management knows that if it&#8217;s possible to enter an invalid value (such as a 5 digit phone number) some user will do it someday.&nbsp; In some cases bad data is rare and other cases just plain prevalent.&nbsp; The other issue is how that impacts your organization.&nbsp; Sometimes the invalid data will just be informational and not a big impact, however, in other cases this can impact reporting, automated processes, data exports/imports and many other systems.</p>
<p>&nbsp;</p>
<p>So, I came up with our current data auditing system.&nbsp; We started it up back in June, 2006 and it&#8217;s been a great help.&nbsp; We currently have 60 checks on our SIS that run various times of the day.&nbsp; Each check is really just a simple SQL statement that looks for errors and stores these in a violations table.&nbsp; After each job a report with the results is sent to the relevant users.&nbsp; Typically we have only a few jobs, most of which run at night and by the morning staff have the latest error report in their email.&nbsp; </p>
<p>&nbsp;</p>
<p>This has been a real labor saver as data entry errors are caught within 24 hours.&nbsp; Those who are responsible for the data usually have the information fresh in their minds or the reference paperwork readily at hand.&nbsp; We have to send various reports to the state several times in the year.&nbsp; In the past, before we had audits, many of the reported fields were not actively maintained and we would get thousands of errors that needed to be corrected before we submitted our reports.&nbsp; Now, the errors are corrected by the next day.&nbsp; When it comes time to submit the reports it&#8217;s a much faster and less stressful process.</p>
<p>&nbsp;</p>
<p>Currently our audit system is in a very 1.0 stage.&nbsp; It only runs on our SIS data since that is what it was originally created for.&nbsp; Also, it&#8217;s entire maintained in SQL by our database managers (3 of us).&nbsp; There is no UI at all.&nbsp; It works, and is great for a 1.0 venture if I am allowed to say so.&nbsp; But it&#8217;s definitely time for a 2.0 version.</p>
<p>&nbsp;</p>
<p>Here are just a few features I&#8217;m looking to put into the 2.0 version:</p>
<ul>
<li>Easy to use web UI</li>
<li>Make use of ASP.Net security and roles</li>
<li>Able to audit ANY data through various data providers:</li>
<ul>
<li>SQL</li>
<li>Active Directory</li>
<li>Exchange</li>
<li>File System</li>
<li>IIS logs</li>
<li>Etc.</li>
</ul>
<li>Better reporting system</li>
<li>Easily setup generic audits on fields such as:</li>
<ul>
<li>Non-empty</li>
<li>Alpha</li>
<li>Numeric</li>
</ul>
<li>Real-time audits (such as using triggers in SQL)</li>
</ul>
<p>&nbsp;</p>
<p>I&#8217;m thinking about putting this on CodePlex once I have the basic framework up and running.&nbsp; I have no ETA on this project since it&#8217;s rare that we get a lot of &#8220;free&#8221; time to work on things like this.</p>
<p>&nbsp;</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b111ae16-96f2-4cdf-bf5a-64983fac8bf7" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Data%20Auditing" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Data Auditing</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/10/08/sql-data-auditing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SQL Injection Attacks</title>
		<link>http://mattpenner.info/2008/09/12/sql-injection-attacks/</link>
		<comments>http://mattpenner.info/2008/09/12/sql-injection-attacks/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 04:14:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Fun]]></category>

		<category><![CDATA[SQL Injection Attack]]></category>

		<guid isPermaLink="false">http://mattpenner.info/?p=40</guid>
		<description><![CDATA[What fun.  Looks like a good friend of mine, James Johnson (also the president of the IE .Net User&#8217;s Group) got attacked by a potential SQL injection.  Fortunately he&#8217;s pretty up on his secure coding so it wasn&#8217;t a problem.  Props to James!
Anyway, he threw it my way because he thought I&#8217;d be interested.  Was [...]]]></description>
			<content:encoded><![CDATA[<p>What fun.  Looks like a good friend of mine, <a title="During Lunch blog" href="http://www.duringlunch.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.duringlunch.com');" target="_blank">James Johnson</a> (also the president of the <a title="IE .Net User Group website" href="http://www.iedotnetug.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.iedotnetug.org');" target="_blank">IE .Net User&#8217;s Group</a>) got attacked by a potential SQL injection.  Fortunately he&#8217;s pretty up on his secure coding so it wasn&#8217;t a problem.  Props to James!</p>
<p>Anyway, he threw it my way because he thought I&#8217;d be interested.  Was a pretty nasty one.  Take a look at <a title="Blog post on James's SQL Injection Attack attempt" href="http://www.duringlunch.com/post/2008/09/A-new-type-of-SQL-Injection-attack.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.duringlunch.com');" target="_blank">his write up</a> and you can also see my comments there.</p>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/09/12/sql-injection-attacks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TortoiseSVN - What&#8217;s the point of Clean Up and why doesn&#8217;t it work?</title>
		<link>http://mattpenner.info/2008/09/10/tortoisesvn-whats-the-point-of-clean-up-and-why-doesnt-it-work/</link>
		<comments>http://mattpenner.info/2008/09/10/tortoisesvn-whats-the-point-of-clean-up-and-why-doesnt-it-work/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 22:18:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://mattpenner.info/2008/09/10/tortoisesvn-whats-the-point-of-clean-up-and-why-doesnt-it-work/</guid>
		<description><![CDATA[This was a question I got from a colleague today.&#160; 
In my experience (which certainly isn&#8217;t exhaustive) a clean up is required when I&#8217;ve done something that svn didn’t expect.&#160; Typically this is where I&#8217;ve manipulated files on my own without using the TortoiseSVN tools.&#160; Eventually they get in such a state that svn simply [...]]]></description>
			<content:encoded><![CDATA[<p>This was a question I got from a colleague today.&nbsp; </p>
<p>In my experience (which certainly isn&#8217;t exhaustive) a clean up is required when I&#8217;ve done something that svn didn’t expect.&nbsp; Typically this is where I&#8217;ve manipulated files on my own without using the TortoiseSVN tools.&nbsp; Eventually they get in such a state that svn simply doesn&#8217;t know how to resolve things.&nbsp; One example comes to mind where I have deleted my .svn folder in a directory.&nbsp; Now, according to svn, that directory is suddenly missing and an unversioned directory of the exact same name exists, and therefore cannot be replaced.</p>
<p>In many cases the Clean Up tool can fix simple mistakes, but in the example above svn simply needs help.&nbsp; If I can&#8217;t fix what&#8217;s going on then I&#8217;ll typically just delete the entire project folder and check out a brand new copy.&nbsp; This is usually far faster than actually trying to fix what went wrong.&nbsp; If I have made changes that I don&#8217;t want to loose then I check out the project into a brand new directory, add the changes to that version (either through VS 2008 or by just manually dragging over files) and do any manipulation such as renames, deleted, etc with Tortoise-svn.</p>
<p>Just yesterday I was working with an SSRS 2005 project.&nbsp; Our set of reports had grown over time so we decided to organize them into folders.&nbsp; VS 2005 cannot do this.&nbsp; Our strategy was to create one solution for the set of reports, containing a separate project for each subgroup.&nbsp; This really helped organize everything, but there was no simple way to do this using VS 2005 and svn.&nbsp; Either we create the new projects and move\rename all the reports between projects using VS 2005, and svn was totally lost, or we did everything in svn, which confused VS 2005 and ultimately broke a lot of links.</p>
<p>I decided on the first option, to simply do it all in VS 2005 then commit the changes in svn.&nbsp; svn reported a lot of missing files and a lot of unversioned files after the change but I just marked the missing ones as deleted and committed the unversioned ones.&nbsp; While I technically lost the history in svn of the development of the files I have rarely needed to view changes past a few revisions and I think any intelligent person can see what we did.</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e1f89c88-478f-47a2-b34c-51002dc1e4b1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Clean%20Up" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">Clean Up</a>,<a href="http://technorati.com/tags/SSRS" onclick="javascript:pageTracker._trackPageview('/outbound/article/technorati.com');" rel="tag">SSRS</a></div>
]]></content:encoded>
			<wfw:commentRss>http://mattpenner.info/2008/09/10/tortoisesvn-whats-the-point-of-clean-up-and-why-doesnt-it-work/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
