<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-5306712688887994524</atom:id><lastBuildDate>Tue, 01 Oct 2024 12:32:23 +0000</lastBuildDate><category>LINQ</category><category>frameworks</category><category>rant</category><title>C How # You Really Are;</title><description>The nerdy thoughts of Josh Springer. Sometimes they are nerdy, sometimes they aren&#39;t. But they are my thoughts, not yours. If you have a problem with them, stop reading, its a free country (for now).</description><link>http://flipstechnologyposts.blogspot.com/</link><managingEditor>noreply@blogger.com (Flip44)</managingEditor><generator>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-6988330839984142549</guid><pubDate>Tue, 16 Feb 2010 00:31:00 +0000</pubDate><atom:updated>2010-02-15T19:49:18.704-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">frameworks</category><category domain="http://www.blogger.com/atom/ns#">rant</category><title>When using frameworks isn&#39;t useful</title><description>This post is more of a rant than a post of information. First off, I want to apologize for not posting in the last 8 months. I have made it a person goal to post at least once a month. Even if it&#39;s nothing relevant (like this post).&lt;br /&gt;&lt;br /&gt;So everyone uses frameworks. Whether it be &lt;a href=&quot;http://nhibernate.org&quot;&gt;Nhibernate &lt;/a&gt;for data access, &lt;a href=&quot;http://www.castleproject.org/container/index.html&quot;&gt;Windsor Container &lt;/a&gt;for your IoC needs, or even things like &lt;a href=&quot;http://www.asp.net&quot;&gt;ASP.NET&lt;/a&gt; or &lt;a href=&quot;http://code.google.com/p/fubumvc/&quot;&gt;FubuMVC &lt;/a&gt;for your UI concerns.&lt;br /&gt;&lt;br /&gt;Frameworks are great. I love them in fact. The less code I need to write, the better. Plus many frameworks come with unit tests. How great is that? I get fully tested code, usually from people who are much more skilled than myself.&lt;br /&gt;&lt;br /&gt;However, things can go wrong. We use several frameworks at work, including a home grown framework. One of the third party frameworks we use (which will remain nameless) recently got an upgrade. The upgrade was quite intrusive. It caused several compilation errors which were well noted in the documentation which was great. The documentation discussed why changes were made, why they broke existing code, and were just &quot;good&quot; in terms of documentation. Props to the framework owners.&lt;br /&gt;&lt;br /&gt;Got the compilation errors fixed after a few days, ran the unit test, everything passed. I thought, great, that was painless. Then we went to test and beta (yes we have multiple environments) and things &quot;seemed&quot; ok. Memory became a little bit more than in the past, but I figured its test and beta. To production we went, within two days, shut down we were. Luckily, the app is a windows service, so being shut down isn&#39;t all that bad. The problem appears to be a memory leak in event handling. Things are wired up for property changed and list changed all over the place. Which is great, except for the fact that we weren&#39;t even using these events.&lt;br /&gt;&lt;br /&gt;So after getting &lt;a href=&quot;http://www.jetbrains.com/profiler/&quot;&gt;dotTrace &lt;/a&gt;up and running in the free trial mode, I saw that PropertyChanged event was my menace. It had well over 90% of the memory being eaten up. So I went in and decided to remove the &quot;framework&quot; from my app. I started with the most commonly used objects, and the performance numbers seemed a little more &quot;normal&quot;. Went to production again, took three days this time, then shut down again.&lt;br /&gt;&lt;br /&gt;By now I&#39;m thinking, man, this is really painful. I thought frameworks were supposed to help you, not hinder you. I had used other frameworks and I had never had a new version kill the app as much as this.&lt;br /&gt;&lt;br /&gt;What was I supposed to do?&lt;br /&gt;&lt;br /&gt;Had a meeting with our team, group decision, start removing the framework. Define our own base functionality that we were using in the framework and scrap the rest of it.&lt;br /&gt;&lt;br /&gt;Overall, there wasn&#39;t much for this app to change. Took less than 2 days to completely remove all references, however, I cannot imagine what would happen if some more important frameworks started to see issues like this. What if System.Web started eating a few hundred bytes every time you created a web control and never released it? What if Nhibernate decided that it was going to internally store all queries sent to the DB in a static variable? What if Windsor Container started returning the wrong service after two weeks without an app recycle?&lt;br /&gt;&lt;br /&gt;Makes you wonder.....if you depended on a framework to run your personal life, how much trust would you give it? Would you let a framework feed your newborn after testing for a few hours? Would you let a third party teach your toddler to use the potty?&lt;br /&gt;&lt;br /&gt;What if everything started going great, then the frameworks got a magic upgrade??&lt;br /&gt;&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2010/02/when-using-frameworks-isnt-useful.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-5025527742385788604</guid><pubDate>Thu, 30 Jul 2009 00:40:00 +0000</pubDate><atom:updated>2009-07-29T21:01:55.567-04:00</atom:updated><title>SQL Server 2008, Strongly Typed DataSets and SQL Data Tables</title><description>Been a while since my last post, but I figured I would put this out there since I couldn&#39;t really find anything on google after searching for only a few minutes.&lt;br /&gt;&lt;p&gt;If you plan on using data table types for SQL2008 or are currently using them, watch out for this GOTCHA.&lt;/p&gt;      &lt;p&gt;We were using custom data sets in visual studio so that we had compile time checking of the data table types for use in some SQL Stored Procs. However, after pounding my head for the past few hours, I found out the following&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Don’t use strongly typed data tables when using SQL2008 data table types and here is why.&lt;/p&gt;    &lt;p&gt;Apparently .NET looks at how you created your DataColumns and the order you create them. With custom data tables with custom data sets (right click folder -&gt; Add New Item -&gt; Data Set ---- then complete the wizard), I am not able to get the columns created properly to match what’s in the database schema.&lt;/p&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtuZa5IIcakV9xHPKwfhVWwAOJIEjqddA_uCbzCT3DRzeRFODAUlUqdiGg3cGR2gJcYDw-tWVuf34X_VKyPhSuZBR_PPTfBozpUSRyMKYkqDcq45PifCYGIyZN_IQv2Ns1YhJYsUPF-NMR/s1600-h/tableType.png&quot;&gt;&lt;img style=&quot;margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 283px; height: 89px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtuZa5IIcakV9xHPKwfhVWwAOJIEjqddA_uCbzCT3DRzeRFODAUlUqdiGg3cGR2gJcYDw-tWVuf34X_VKyPhSuZBR_PPTfBozpUSRyMKYkqDcq45PifCYGIyZN_IQv2Ns1YhJYsUPF-NMR/s320/tableType.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364048117169511922&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is our custom data set definition…in this case, pay attention to the LocationConstraintGeoPoints table…&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgONy4aNtF9MyGYNSPvyk8YeqrdNYf5SP6FN_F3-9synxIBX8-cZDyNl_0Y13gwBlb8iS3kitrY5c7kG9-Sy1ZdimibjOG9fdtLhe5ZEYpo9WRAkRZMCDq4GRnMWxTXCVZV3fOhhRrvn7YH/s1600-h/dataset.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 290px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgONy4aNtF9MyGYNSPvyk8YeqrdNYf5SP6FN_F3-9synxIBX8-cZDyNl_0Y13gwBlb8iS3kitrY5c7kG9-Sy1ZdimibjOG9fdtLhe5ZEYpo9WRAkRZMCDq4GRnMWxTXCVZV3fOhhRrvn7YH/s400/dataset.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364048386963434818&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;p&gt;And we used this code to populate the table…&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;StoredProcTableTypes&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;LocationC&lt;wbr&gt;onstraintGeoPointsDataTable&lt;/span&gt; geocodeTable = &lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;StoredProcTableTypes&lt;/span&gt;.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;LocationC&lt;wbr&gt;onstraintGeoPointsDataTable&lt;/span&gt;();&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;;font-size:100%;color:blue;&quot;  &gt;foreach&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt; (&lt;span style=&quot;color:blue;&quot;&gt;var&lt;/span&gt; point &lt;span style=&quot;color:blue;&quot;&gt;in&lt;/span&gt; Location.Polys.SelectMany(&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;f =&gt; f.Points))&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;   &lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;StoredProcTableTypes&lt;/span&gt;.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;LocationC&lt;wbr&gt;onstraintGeoPointsRow&lt;/span&gt; row = geocodeTable.&lt;wbr&gt;NewLocationConstraintGeoPoints&lt;wbr&gt;Row();&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;   row.Latitude = point.Latitude;    //Debugged value 46&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;   row.Longitude = point.Longitude;  //Debugged value -70&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;   geocodeTable.&lt;wbr&gt;AddLocationConstraintGeoPoints&lt;wbr&gt;Row(row);&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt; &lt;/p&gt;  &lt;p&gt;So far so good right…everything looks like it matches, I have compile time checking of the fields, etc…&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Upon first run of the code the following was being generated in SQL trace. Notice -70 longitude was first followed by 46 latitude. However, this statement would be adding LATITUDE as the first parameter and LONGITUDE as the second…&lt;/p&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivXM12Pzvbj4fU4mb_yrE7CQiSmc8YReuSqLcDUu9ILjTn1-GrcMa2xKQigyDqz9aMnuqqBqB51a1noLJUpXNjDdMns8vL4py59XnJL-GQ2KnGkDC401YlNA4qRFH4jfZO3WDRVw8Ka32I/s1600-h/sqlTraceBefore.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 336px; height: 58px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivXM12Pzvbj4fU4mb_yrE7CQiSmc8YReuSqLcDUu9ILjTn1-GrcMa2xKQigyDqz9aMnuqqBqB51a1noLJUpXNjDdMns8vL4py59XnJL-GQ2KnGkDC401YlNA4qRFH4jfZO3WDRVw8Ka32I/s400/sqlTraceBefore.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364048819881685698&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;After trying to delete and re-add columns to the data table in the dataset designer, I finally gave up…I hard coded the following…just guessing this would fix the issue…&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;System.Data.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;DataTable&lt;/span&gt; geocodeTable = &lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; System.Data.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;DataTable&lt;/span&gt;();&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;geocodeTable.Columns.Add(&lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; System.Data.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;DataColumn&lt;/span&gt;(&lt;span style=&quot;color: rgb(163, 21, 21);&quot;&gt;&quot;&lt;wbr&gt;Latitude&quot;&lt;/span&gt;, &lt;span style=&quot;color:blue;&quot;&gt;typeof&lt;/span&gt;(&lt;span style=&quot;color:blue;&quot;&gt;decimal&lt;/span&gt;)));&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;geocodeTable.Columns.Add(&lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; System.Data.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;DataColumn&lt;/span&gt;(&lt;span style=&quot;color: rgb(163, 21, 21);&quot;&gt;&quot;&lt;wbr&gt;Longitude&quot;&lt;/span&gt;, &lt;span style=&quot;color:blue;&quot;&gt;typeof&lt;/span&gt;(&lt;span style=&quot;color:blue;&quot;&gt;decimal&lt;/span&gt;)));&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;;font-size:100%;color:blue;&quot;  &gt;foreach&lt;/span&gt;&lt;span style=&quot;font-size:100%;&quot;&gt; (&lt;span style=&quot;color:blue;&quot;&gt;var&lt;/span&gt; point &lt;span style=&quot;color:blue;&quot;&gt;in&lt;/span&gt; Location.Polys.SelectMany(f =&gt; f.Points))&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;{&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;  System.Data.&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;DataRow&lt;/span&gt; row = geocodeTable.NewRow();&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;  row[&lt;span style=&quot;color: rgb(163, 21, 21);&quot;&gt;&quot;Latitude&quot;&lt;/span&gt;] = point.Latitude;&lt;/span&gt;&lt;/p&gt;  &lt;p  style=&quot;font-family:courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;  row[&lt;span style=&quot;color: rgb(163, 21, 21);&quot;&gt;&quot;Longitude&quot;&lt;/span&gt;] = point.Longitude;&lt;/span&gt;&lt;/p&gt;  &lt;p face=&quot;courier new&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;  geocodeTable.Rows.Add(row);&lt;/span&gt;&lt;/p&gt;  &lt;p style=&quot;font-family: courier new;&quot;&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I ran the test again, this time notice the 46 (latitude) is now the first parameter in the SQL trace followed by the -70 (longitude).&lt;/p&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMHsprYLb54TQtHEU9G1U0hPGHeOh16CCnpqZ8HBrCDSeFbvcPMrmKe97s3fErvgo8bI1rZ2xf8E1v25DMM62feQwAdoJCdo9n8e523u8Ur3la3cQ54TGbNJx7Conne1RkCc5pOUjrIKRl/s1600-h/sqlTraceAfter.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 46px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMHsprYLb54TQtHEU9G1U0hPGHeOh16CCnpqZ8HBrCDSeFbvcPMrmKe97s3fErvgo8bI1rZ2xf8E1v25DMM62feQwAdoJCdo9n8e523u8Ur3la3cQ54TGbNJx7Conne1RkCc5pOUjrIKRl/s320/sqlTraceAfter.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364049582854826530&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;So I couldn’t stop there, I of course, had to swap the two .Columns.Add() calls to verify my theory…and it performed the same as the first read putting the -70 longitude first and 46 latitude last…&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQaPHHNjT8KraPiER2qVXMXOwMPDfUSjPRsfd6w10Cr4jhDiOMaXeyLXceCKaI4G1uUVXuctKmZEItTjzWzulxTixoFFYEDQetqXAHaja_ZCYhnPw0GzbyGkZuIC3XUzxfom47wxGxfyqB/s1600-h/sqlTraceVerify.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 55px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQaPHHNjT8KraPiER2qVXMXOwMPDfUSjPRsfd6w10Cr4jhDiOMaXeyLXceCKaI4G1uUVXuctKmZEItTjzWzulxTixoFFYEDQetqXAHaja_ZCYhnPw0GzbyGkZuIC3XUzxfom47wxGxfyqB/s320/sqlTraceVerify.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364050942945024706&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;font-size:16;&quot;&gt;So what’s the point…&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;BE CAREFUL…definitely run trace to make sure your tables are being created properly in the code…and definitely make sure if you change said data table definitions in the database, you use extra caution…&lt;/p&gt;    &lt;p&gt;For us, this is not updating data…it runs great, works 100% of the time when both numbers are equal, so had our unit test not been updated to used random data we could have been totally screwed…imagine if this was being used to update some seriously important data and the data types and constraints matched, but the data we were sending was completely invalid…OUCH!!!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2009/07/sql-server-2008-strongly-typed-datasets.html</link><author>noreply@blogger.com (Flip44)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtuZa5IIcakV9xHPKwfhVWwAOJIEjqddA_uCbzCT3DRzeRFODAUlUqdiGg3cGR2gJcYDw-tWVuf34X_VKyPhSuZBR_PPTfBozpUSRyMKYkqDcq45PifCYGIyZN_IQv2Ns1YhJYsUPF-NMR/s72-c/tableType.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-3866336213188373553</guid><pubDate>Wed, 08 Apr 2009 15:52:00 +0000</pubDate><atom:updated>2009-04-15T20:45:16.444-04:00</atom:updated><title>Test This...</title><description>&lt;div&gt;I&#39;ve been doing a lot of thinking lately about unit tests. The project I&#39;m working on had to have unit testing, not just because every project should have unit tests, but because this is our make or break business application. This application has major, major impact on our business. If something were to fail in the application in production, it has massive implications to our bottom line. So our team spent a lot of time working on unit tests.&lt;br /&gt;&lt;br /&gt;This post isn&#39;t going to talk about how to unit test, different products for unit testing, mocking, or anything like that. What I&#39;d like to talk about is how in the world you test database interactivity. Now I&#39;m sure any super code guru who reads this will say, keep the database out of the unit test, but we can&#39;t. There are several database processes that are so crucial, that any failure of said process will cause extreme cascading issues in our production environment. As well as, some of the processes being so complicated (some SPs over 1000 lines of code) that we really need to verify any changes to ensure they don&#39;t break other pieces of other actions in the process.&lt;br /&gt;&lt;br /&gt;So how in the heck do you test a database process? Well, that is what we are going to try to figure out. As well as when we should really test the database, what we use to test it, how we generate &quot;fake-real&quot; data. I am going to describe several of the scenarios we used for testing the database.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;The Brute Force Method&lt;/span&gt;&lt;br /&gt;Some of our stored procs can be tested in a brute force manner. The unit test itself inserts a bunch of data into the database (keeping track of what should and shouldn&#39;t happen in List&lt;t&gt; lists). Then we run the stored procedure and ensure what we thought would happen, did, and also ensure that some random data that shouldn&#39;t have changed didn&#39;t.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;The Hold My HandManual Way&lt;/span&gt;&lt;br /&gt;There are some tests that we just haven&#39;t had enough time to actually implement as a unit test, but we still verify them occassionally the old fashioned hold my hand way. These are usually sets of Sps that get called together in a batch (only in our test do they get called together, in production they are setup on DB Timers to run periodically with no user intervention). So anyways, usually we ensure some data is setup, then we run all the steps, ensuring that along every step what should have moved did, and what was still not ready to move, didn&#39;t. Now these are the tests that are really the more important ones, and unfortunately for us, they are the un-unit tested tests.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;The If It Compiles, It Runs, Guaranteed!!&lt;/span&gt;&lt;br /&gt;Like most things in life, we usually take code gen for granted. We do use some code gen tools to do some simple things like SELECT * FROM TABLE BY PRIMARY KEY. Yes trivial queries that a monkey can write and execute. Let&#39;s face it though, monkeys are DUMB! There are always quirks to code gen. No matter what the tool, I&#39;ve always run across scenarios where one minor thing causes the code gen to just gen code that doesn&#39;t run. Sps are no substitute. So this method is no testing at all. Its just hit F5 after you type the code, and it will run, Guaranteed, until you go to prod and someone actually puts some REAL data together, then failure, Sp breaks.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Database unit testing is really something I haven&#39;t been able to dig a lot up on. I been searching online and everyone talks about Data Dude, well Data Dude may work, but it generates the most crappy SQL migration scripts I&#39;ve ever seen. Once again, code gen that doesn&#39;t gen code correctly. Some people out there love data dude, well not me. Anything that deletes and recreates a table to simply add a column is just plain dumb. I&#39;m sorry. Maybe I&#39;m just an idiot and I&#39;m definitely NOT a Data Dude guru, but man, to add a column and update a few SPs, was like 2000 lines of SQL code in teh auto gen file when there were a total of probably 500 lines of actual code all together.&lt;br /&gt;&lt;br /&gt;If anyone out there happens to read this and knows of some good database unit testing frameworks or examples, comment on this post, I would love to hear about it.&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;To the end, I shall go, but to the beginning is where I end up.&lt;/div&gt;</description><link>http://flipstechnologyposts.blogspot.com/2009/04/test-this.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-628846351261117289</guid><pubDate>Sat, 04 Apr 2009 00:22:00 +0000</pubDate><atom:updated>2009-04-08T11:52:23.820-04:00</atom:updated><title>More Abstraction...</title><description>So the &lt;a href=&quot;http://flipstechnologyposts.blogspot.com/2009/04/abstract-this.html&quot;&gt;last post &lt;/a&gt;I talked about abstracting away config settings. A fellow &lt;a href=&quot;http://jaychapman.blogspot.com/&quot;&gt;guru&lt;/a&gt; sent me this &lt;a href=&quot;http://www.4guysfromrolla.com/articles/032807-1.aspx&quot;&gt;link &lt;/a&gt;that they implemented where he used to work. Just another way of hiding implementation. There are multiple definitions for abstraction. The last post talked about abstract as hiding away implementation. This post is going to talk about abstraction in its c# terminology. I&#39;ve been reading &lt;a href=&quot;http://oreilly.com/catalog/9780596007126/&quot;&gt;Head First Design Patterns&lt;/a&gt; and I had a DUH moment the other day. For a while now, I&#39;ve heard people talking about using interfaces, and whatnot, but I never really got it until I read HFDP. HFDP talks about developing around an interface versus and implementation. And interface can also be an abstract class. Using an interface you don&#39;t really have to know about the code, you just care about the API the interface gives you.&lt;br /&gt;&lt;br /&gt;So this week the app we have been working needed a windows service to allow multiple ways to import data into our system. Currently there is only one third party vendor, but in a week, we&#39;ll have another, and in a month a third, projecting out to almost 20 by end of year and more to come. So obviously, we needed to design something that was simple to use, easy to implement, and our windows service didn&#39;t know to know anything about the implementation. So we sat down and took into consideration several things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The interface needs a start method to kick off the actual importer&lt;/li&gt;&lt;li&gt;The interface needs a safe way to shut down the importer&lt;/li&gt;&lt;li&gt;The interface needs to be disposable&lt;/li&gt;&lt;li&gt;The interface needs to be able to set several constant properties (constant meaning, we always SET or GET them, not that they are actually public const variables)&lt;/li&gt;&lt;li&gt;The interface needs to pump several messages to the service (expose events)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So obviously this is a pretty simple interface. So our interface was pretty simple (it has these properties and methods and that&#39;s it). Now that is all fine and dandy except if I have 20 classes that implement all the same events, then I have 20 * # events of methods like this private void OnSomeEvent() { if (SomeEvent != null) SomeEvent(this, EventArgs.Empty); }. So here is where the abstraction piece comes into play.&lt;br /&gt;&lt;br /&gt;We decided to create an abstract base class that inherits from the interface. Then in the class, we wire up all the event firing methods, as well as implementing all the methods of the interface. But here comes the really sweet ass part. We basically wrote the base importer in a way that used abstract methods for things like retrieving the data, validating it, converting it, etc. So now, the derived importers (the actual stuff we care about and have to write) is so basic and &quot;plain&quot; that implementing a new importer will be as simple as inheriting from a base abstract class and implementing its abstract methods.&lt;br /&gt;&lt;br /&gt;Now its a bit more complicated because we also are using interfaces for the data we are actually converting, so as long as what we are converting (ie: each row in a CSV or XML file) inherits from a second inteface, the abstract base class doesn&#39;t care about the actual implementation of the derived class, and it really has no freaking idea about the data we are actually importing.&lt;br /&gt;&lt;br /&gt;So the really awesome thing. When I build my unit test to test that the windows service actually does what its supposed to, I can now stub out some dummy classes and use those. So my derived abstract class can do things like:&lt;br /&gt;&lt;br /&gt;protected override IList GetRecords() { return new List( new int[] { 1, 2, 3, 4, 5 }); }&lt;br /&gt;protected override bool ShouldIDoSomething() { return true; }&lt;br /&gt;&lt;br /&gt;And my test can guarantee certain things in the windows service. Now, I could probably move this into another class, blah, blah, blah. But for lack of adding more code, its gonna live and die in the service itself.&lt;br /&gt;&lt;br /&gt;So to conclude, this whole coding to an interface is really worth while. I have really had a DUH moment. I feel like such a dumbass, but I&#39;m glad I was recommended the HFDP book. I can&#39;t wait to read the other 500 pages.&lt;br /&gt;&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2009/04/more-abstraction.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-2112928504843830894</guid><pubDate>Thu, 02 Apr 2009 16:50:00 +0000</pubDate><atom:updated>2009-04-02T13:07:46.634-04:00</atom:updated><title>Abstract This...</title><description>Its been a while since I last posted. I think almost a full year. A lot has changed. I&#39;m must stupider, uglier and I just don&#39;t know anything about technology anymore. Well most of that is not true, but I am uglier. At least that&#39;s what the wife says.&lt;br /&gt;&lt;br /&gt;Anyways, to my point.&lt;br /&gt;&lt;br /&gt;Today I saw some code that I see quite frequently, and I started thinking to myself, man, that is old school.&lt;br /&gt;&lt;br /&gt;string someVal = ConfigurationManager.AppSettings[&quot;SomeSettingName&quot;];&lt;br /&gt;string reqVal = Request.QueryString[&quot;ParamName&quot;];&lt;br /&gt;&lt;br /&gt;Now you might think to yourself, I have that all over in my code. Well, then you&#39;ll really enjoy, or hate this point. A few months ago, I got to work on a project with a fellow who is way smarter than myself, and I saw something that just clicked for me. He basically took his AppSettings and wrapped them in a public static class. How ingenious right? Now his code doesn&#39;t have to know about ConfigurationManager, and if he changes it to read from a database, he changes code in one place.&lt;br /&gt;&lt;br /&gt;**New Code:&lt;br /&gt;string someVal = ProjectConfigSettings.SomeSettingName;&lt;br /&gt;&lt;br /&gt;So how does that tie into the querystring you ask? Well I took his idea one step further. I started creating a public static class for all my querystring variables. Now, if I every changes the name of a variable, I change it in one place, and my entire application knows about it. Obviously, this takes a bit of discipline to force myself to add the extra class and constant values, but once I do it, I am thankful, especially when I start adding parameters to a page I didn&#39;t expect to add parameters to.&lt;br /&gt;&lt;br /&gt;**New Code:&lt;br /&gt;string reqVal = Request.QueryString[QueryStringConstants.ParamName];&lt;br /&gt;&lt;br /&gt;So this post is going to explode the abstract-ness of code. There are lots of things you can do to &quot;hide&quot; code, or shortcut major changes. When you develop something, really think how you are going to use it. You don&#39;t need to add 10 layers of sub classes, blah, blah, but you should really think, if I change how I do X, how much will it impace my code. If you change ConfigurationManager.AppSettings[&quot;Gary&quot;] to ConfigurationManager.AppSettings[&quot;GaryValue&quot;] what type of impact does it have? In the new fashion of abstraction, your application changes one (usually one) line of code in an abstracted way. You don&#39;t change your business code, UI code, or service layer code, you change your ConfigSetting class. One class is updated, and the change propogates out. If I&#39;m worried about Google SEO, my querystring parameter now has a really helpful name instead of q1, I can use StreetAddressLine1 and my app doesn&#39;t know the difference.&lt;br /&gt;&lt;br /&gt;I hope the next time you write some code, you really think, if I change how I do this, what impact does it have on my app??&lt;br /&gt;&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2009/04/abstract-this.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-103832739814290167</guid><pubDate>Thu, 28 Aug 2008 10:34:00 +0000</pubDate><atom:updated>2008-08-28T06:49:45.029-04:00</atom:updated><title>Regurgitation...</title><description>I just finished reading a post by &lt;a href=&quot;http://codebetter.com/blogs/jeremy.miller/archive/2008/08/24/a-train-of-thought-august-24th-2008-edition.aspx?CommentPosted=true#commentmessage&quot;&gt;Jeremy Miller&lt;/a&gt; on CodeBetter.com and WOW. Its a lengthy article, so I&#39;ve put it off for a few days, but man it touched my heart. Jeremy mentions a lot of great points. His article starts out about design and not over engineering, moves onto some cynical analysis of tools that are out in the world today, and finishes with some a comedic reference to good old George Carlin. This post is going to be a regurgitation of several posts I&#39;ve read in the past few days. I recently starting reading blogs that were recommended by my colleagues, so I&#39;m getting a lot more exposure to little tidbits of information, and opinions that match my own, and that I disagree with.&lt;br /&gt;&lt;br /&gt;So here goes...&lt;br /&gt;&lt;br /&gt;There are so many things going on in the .NET space right now its hard to keep them all straight. .NET Framework 3.5 was just RTM with Entity Spaces, VS 2k8 SP 1 is out, TFS 2k8 SP 1 is out, new Windows and SQL servers, Silverlight, WPF, WCF, WMD. Well, maybe we still havent&#39; found WMD, but &quot;We Got &#39;em&quot;.&lt;br /&gt;&lt;br /&gt;If you haven&#39;t noticed, technologies are being adopted all over the place. Even where they don&#39;t make sense. NBC used Silverlight to rebroadcast its coverage of the olympics. Great use guys. I have heard nothing but praise for colleagues  about how cool it was. This was great for Microsoft too, because a HUGE player finally saw that Silverlight will CRUSH Flash. I&#39;m sure there are those Flash guys who say, no Silverlight is a fad. To that I answer, how many ActionScript programmers do you know?? And how many C++, C#, VB programmers to know?? And I believe I just read an article that you can start using things like Ruby inside of Silverlight with its dynamic language capabilities. Flash will still own the web animation world for now, but I see Silverlight taking over in a few years. Especially when ESPN starts using it to stream its videos. Its only a matter of time before ABC picks up Silverlight now that NBC was the guinea pig.&lt;br /&gt;&lt;br /&gt;Then there are technologies that have their place, but can be overburdensome. For example, NHibernate 2.0 just came out. I have not yet played or looked at the code, but read several posts about its expansion in lines of code, classes, and namespaces as well as its lack of commenting. To that I say, give it a few months. People will start adding to the open source code and voila, you have all the comments etc. You also can download the ENTIRE NHibernate documentation online. Just because you don&#39;t have intellisense doesn&#39;t mean the documentation isn&#39;t there. Entity Framework also just came out. From what I have read and seen videos on, this is Microsofts first real ORM. Powerful, yes. You can tie specific objects to stored procedures, you get to use LINQ, you have a great object model and object GRAPH. However, there isn&#39;t a huge community around it yet like NHibernate. Maybe in a few years Entity Framework will catch on, but as with any major Micrsoft technology, I&#39;ll wait until SP1 comes out.&lt;br /&gt;&lt;br /&gt;That is my rant for the day. Lots of things have happened over the past few months. I transitioned into a new position at work. I&#39;m working on a rewrite of an old web app we had with all sorts of integration points with other legacy systems. Quite interesting actually, and quite a learning experience having to deal with applications that just STOP working for no apparent reason. As we continue in the project, I&#39;ll try to post more about our architecture design and whatnot, why we went with certain things. What worked, what didn&#39;t.&lt;br /&gt;&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/08/regurgitation.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-5185923806658350969</guid><pubDate>Thu, 12 Jun 2008 00:35:00 +0000</pubDate><atom:updated>2008-06-11T20:54:01.528-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">LINQ</category><title>Daisy Chain-LINQ</title><description>First off I want you to know that I have been a HUGE proponent of LINQ since I first read about it in 2006. I still continue to believe that LINQ has and will continue to revolutionize how we as developers write logic. If you don&#39;t agree, that&#39;s great, post a comment why.&lt;br /&gt;&lt;br /&gt;Anyways, on to LINQ and the rest of this post. So today I was posed with building a search screen that reads data from a DB. Yeah, awesome right. Well the DB query would be rather complicated because it flattens out data and joins several tables, and I really wasn&#39;t in the mood for all that, so a colleague of mine suggested reading all the data I need into business objects once, caching it, then using LINQ to actually perform the query, so away I went.&lt;br /&gt;&lt;br /&gt;I got my data all loaded just fine. Its on the web so I can use Page.Cache and store it off for all day since its pretty stagnant data. Then on to the cool stuff. I got to thinking, if I could figure out a way to use reflection, I could totally build sorting into my GridView without any sort of SWITCH(SortExpression) to create the order by clause.&lt;br /&gt;&lt;br /&gt;Here is what I came up with.&lt;br /&gt; &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;; color: blue;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt; query = &lt;span style=&quot;color: blue;&quot;&gt;from&lt;/span&gt; item &lt;span style=&quot;color: blue;&quot;&gt;in&lt;/span&gt; _CachedList &lt;span style=&quot;color: blue;&quot;&gt;select&lt;/span&gt; item;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            &lt;span style=&quot;color: blue;&quot;&gt;if&lt;/span&gt; (_SortDirectionAsc) //ViewState property I assign in OnSorting() of GridView&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;                query = query.OrderBy&lt;&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;CachedBLResults&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&gt;(i =&gt; i.GetType().GetProperty(_SortPropertyName).GetValue(i, &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;) &lt;span style=&quot;color: blue;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            &lt;span style=&quot;color: blue;&quot;&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;                query = query.OrderByDescending&lt;&lt;span style=&quot;color: rgb(43, 145, 175);&quot;&gt;CachedBLResults&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;&gt;(i =&gt; i.GetType().GetProperty(_SortPropertyName).GetValue(i, &lt;span style=&quot;color: blue;&quot;&gt;null&lt;/span&gt;) &lt;span style=&quot;color: blue;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;string&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            query = query.Skip(gvBLResults.PageSize * &lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;gvBLResults&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;PageIndex);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            query = query.Take(&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;gvBLResults&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;.PageSize);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;&quot;&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;gvBLResults&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;.DataSource = query.ToList();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;gvBLResults&lt;/span&gt;&lt;span style=&quot;font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;.DataBind();&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;So far this works like a charm. I haven&#39;t yet added in the criteria, which I&#39;ll do tomorrow but that will simply be query = query.Where(i =&gt; i.Field == Criteria.Field); Its amazingly fast too. The slow part of course is loading the data into the Cache from the DB. I can&#39;t believe how easy it was to use Reflection to get the properties and check their values. Of course this example is only limited to columns that contains string values, but I&#39;m sure with some use of Generics you could blow it out to be a lot better.&lt;br /&gt;&lt;br /&gt;I continue to swear by LINQ. I can&#39;t tell you how my custom sort methods I have changed to simply use a LINQ query to be var query = from i in Items order by i.Field select i;&lt;br /&gt;&lt;br /&gt;Just wanted to put a quick post out there for anyone who was trying to use LINQ with Reflection. Hope this helped.&lt;br /&gt;To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/06/daisy-chain-linq.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-1814821797544260090</guid><pubDate>Sat, 17 May 2008 15:10:00 +0000</pubDate><atom:updated>2008-05-17T11:18:35.853-04:00</atom:updated><title>Cool CSV Reader (Another Gotcha)</title><description>So during my testing as I mentioned in the previous article about our IIS7, I identified another gotcha. This one is a biggie, since it adversely affects more people than just ActiveRecord users (and of course those using custom HttpModules), and its not just IIS7 specific. Anyways, while testing a form that uploads a CSV file and uses a DataTable to read the CSV I started getting ODBC driver cannot be found. I was like what the F*. So after talking to the server guys and reading some articles on MSDN, I find out that Microsoft is no longer supporting ODBC text driver for some versions of Windows 2003 64 Bit and Windows 2008 64 Bit. You can download a newly released driver for 2003 &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=000364db-5e8b-44a8-b9be-ca44d18b059b&amp;amp;displaylang=en&quot;&gt;here&lt;/a&gt;. But of course nothing is ready for 2008. So being that this app has to have a CSV reader I thought I&#39;d ask around and a fellow team member found this &lt;a href=&quot;http://www.filehelpers.com/&quot;&gt;CSV / XML super parser&lt;/a&gt; that is of all things OPEN SOURCE. How freaking sweet? It comes with a simple &lt;a href=&quot;http://www.filehelpers.com/wizard.html&quot;&gt;wizard UI&lt;/a&gt; that lets you template out your CSV and builds the code all right there. Its Super Easy. I had replaced my DataTable code with REAL OBJECTS instead of DataTables in less than 15 minutes. Seriously worth downloading and at least looking at the wizard. I have only touched the surface of this little app, but I had to share it with people. Its definitely worth the 15 minutes to download and try out. And there is a lot of documentation online as well. And since its open source, if you find a but, you can fix it. Or better yet, make the app better. That&#39;s about it. I know there isn&#39;t any meat and potatoes with this post, but I had to share a cool, free tool. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/05/cool-csv-reader-another-gotcha.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-8814146479621414838</guid><pubDate>Sat, 17 May 2008 14:53:00 +0000</pubDate><atom:updated>2008-05-17T11:06:02.581-04:00</atom:updated><title>ActiveRecord and IIS7 (Windows 2008) Gotcha</title><description>The other day we migrated some of our test servers to IIS7 so we could test our applications before moving the changes to the production environment. So of course, there were issues. Nothing really super major, but definitely some gotchas to be aware of. One of the first things I noticed was that Lazy Loading stopped working with ActiveRecord. ActiveRecord depends on the ar.sessionscope HTTPmodule because that is where is stores the current NHibernate session. With IIS7, some of the web.config settings have changed &quot;LOCATION&quot;. They still are the same exact settings, just in a different place. I wanted to post something out on my blog because it took me a few days to actually find something online that had some suggestions. There was a google group post I found, that took me to this &lt;a href=&quot;http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis7/&quot;&gt;site&lt;/a&gt; and specifically mentioned I read the &lt;b&gt;Migrating ASP.NET Applications to IIS 7.0 Integrated mode &lt;/b&gt;section. There really is only a small paragraph so I recommend you do the same. Basically IIS7 no longer uses HttpModules in the config section it is usually placed in. It has moved the HttpModules to a new section called &lt;module&gt; as the article mentions. Once I made this change, my Lazy Loading and the &quot;no session scope&quot; found error went away. I hope this quick little post helps someone. It took me a few days to figure it out. I also have to debug some more bugs with IIS7, but I can&#39;t post those until I solve them. Here is a link to the &lt;a href=&quot;http://groups.google.com/group/nhusers/browse_thread/thread/42e822eec19fec2d&quot;&gt;original article&lt;/a&gt; I found online. Unfortunately it wasn&#39;t ActiveRecord specific, so it took me a while to Google it, but thanks to VK, I found the issue.  To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/05/activerecord-and-iis7-windows-2008.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-4253747571236222768</guid><pubDate>Tue, 29 Apr 2008 12:56:00 +0000</pubDate><atom:updated>2008-04-29T08:56:48.461-04:00</atom:updated><title>Day of the Jedi</title><description>&lt;div align=&quot;center&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;object type=&quot;application/x-shockwave-flash&quot; height=&quot;180&quot; width=&quot;310&quot; data=&quot;http://files.poqbum.com/Files/Gens/countdown/countdown/cndplayer.swf?skinn=&quot; allownetworking=&quot;internal&quot; allowscriptaccess=&quot;never&quot; tseconds=&quot;0&quot; thours=&quot;0&amp;amp;tminutes=&quot; tmonth=&quot;5&amp;amp;tday=&quot; msg=&quot;Universal%20Day%20of%20the%20Jedi&amp;amp;tyear=&quot; tcm=&quot;dddcff&amp;amp;tcu=&quot; bg_c=&quot;263172&amp;amp;bg_mc=&quot;&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.dayofthejedi.com/&quot;&gt;Universal Day of the Jedi&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;</description><link>http://flipstechnologyposts.blogspot.com/2008/04/day-of-jedi.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-1206257431984703049</guid><pubDate>Wed, 23 Apr 2008 17:20:00 +0000</pubDate><atom:updated>2008-04-23T13:35:43.349-04:00</atom:updated><title>TFS 2005 HACK For Building Visual Studio 2008 Solutions</title><description>Well, after two days of playing around, some fellow colleagues and I have finally come up with a solution to building Visual Studio 2008 projects / solutions in Team Foundation Server 2005. With several helpful links after a quick google search, we found a total HACK workaround. You can read the &lt;a href=&quot;http://tfsnow.wordpress.com/2007/08/31/building-net-35-applications-with-team-build-2005/&quot;&gt;article here&lt;/a&gt;. Although this solution &quot;worked&quot; it was buggy. Depending on what was passed in the parameters, we were getting errors, plus I wanted to add some logging information so I included a Trace option in my app. To help those in dire need, I am going to post our solution, source code and all. Its pretty much just a console application and its config file that drive everything. Feel free to use this solution.&lt;br /&gt;&lt;br /&gt;A side note to mention, we can still build our custom TFS tasks we were using as well. Also, you need to add a custom parameter to the TFSBuild.RSP file in Team Foundation Server. This setting will tell the TFS build to use the 3.5 framework version of MSBuild. Our solution had to still build old code using the 2.0 framework, so we didn&#39;t want to blindly redirect everything to the 3.5 build. You can adjust the Config setting according to whatever parameter you add. You will need to add a &quot;/p:SOMETHING&quot; in the RSP file as it is passed to MSBuild and if MSBuild doesn&#39;t recognize your parameter your build will fail.&lt;br /&gt;&lt;br /&gt;Here is the code for the console app.&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Diagnostics;&lt;br /&gt;using System.Configuration;&lt;br /&gt;using System.IO;&lt;br /&gt;namespace MSBuild&lt;br /&gt;{&lt;br /&gt;class MSBuild&lt;br /&gt;{&lt;br /&gt;    static MSBuild()&lt;br /&gt;    {&lt;br /&gt;        TextWriterTraceListener listener = new TextWriterTraceListener(System.Configuration.ConfigurationManager.AppSettings[&quot;AppDir&quot;] + &quot;MSBuild_SHIM.log&quot;);&lt;br /&gt;        listener.TraceOutputOptions = TraceOptions.DateTime;&lt;br /&gt;        listener.IndentSize = 4;&lt;br /&gt;        Trace.Listeners.Add(listener);&lt;br /&gt;        Trace.AutoFlush = true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static int Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        bool isVS2k8Solution = false;&lt;br /&gt;        StringBuilder parameters = new StringBuilder(1000);&lt;br /&gt;        Trace.WriteLine(&quot;Beginning Trace: &quot; + DateTime.Now.ToString());&lt;br /&gt;        Trace.WriteLine(&quot; Directory: &quot; + Environment.CurrentDirectory);&lt;br /&gt;        Trace.WriteLine(&quot; Command Line: &quot; + Environment.CommandLine);&lt;br /&gt;        Trace.WriteLine(&quot; Arguments:&quot;);&lt;br /&gt;        foreach (string s in args)&lt;br /&gt;        {&lt;br /&gt;            Trace.WriteLine(&quot; - &quot; + s + &quot;&quot;);&lt;br /&gt;            if (s.Contains(&quot; &quot;))&lt;br /&gt;            {&lt;br /&gt;                parameters.AppendFormat(&quot;\&quot;{0}\&quot;&quot;, s);&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                parameters.Append(s);&lt;br /&gt;            }&lt;br /&gt;            parameters.Append(&quot; &quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            string rspFile = System.IO.File.ReadAllText(Environment.CurrentDirectory + &quot;\\TFSBuild.rsp&quot;);&lt;br /&gt;            if (rspFile.ToLower().Contains(System.Configuration.ConfigurationManager.AppSettings[&quot;VisualStudio2008CompareString&quot;].ToLower()))&lt;br /&gt;            {&lt;br /&gt;                Trace.WriteLine(&quot; *** Building with VS2k8 Flag found&quot;);&lt;br /&gt;                isVS2k8Solution = true;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        catch (Exception ex)&lt;br /&gt;        {&lt;br /&gt;            Trace.WriteLine(&quot; EXCEPTION: &quot; + ex.Message);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // something like &quot;C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\MSBuild.exe&quot;;&lt;br /&gt;        string msbuildexe = System.Configuration.ConfigurationManager.AppSettings[&quot;msbuild2005&quot;];&lt;br /&gt;        if (isVS2k8Solution)&lt;br /&gt;        {&lt;br /&gt;            msbuildexe = System.Configuration.ConfigurationManager.AppSettings[&quot;msbuild2008&quot;];&lt;br /&gt;        }&lt;br /&gt;        Trace.WriteLine(&quot; MSBUILD call routed to : &quot; + msbuildexe);&lt;br /&gt;        Trace.WriteLine(&quot; Firing Off App: &quot; + parameters.ToString());&lt;br /&gt;&lt;br /&gt;        // fire the new msbuild with the actual arguments&lt;br /&gt;        ProcessStartInfo startInfo = new ProcessStartInfo();&lt;br /&gt;        Process myProcess = new Process();&lt;br /&gt;        startInfo.FileName = msbuildexe;&lt;br /&gt;        startInfo.Arguments = parameters.ToString();&lt;br /&gt;        startInfo.WindowStyle = ProcessWindowStyle.Hidden;&lt;br /&gt;        myProcess.StartInfo = startInfo;&lt;br /&gt;        myProcess.Start();&lt;br /&gt;       &lt;br /&gt;        Trace.WriteLine(&quot; &quot; + DateTime.Now.ToString() + &quot; -- MSBuild Started&quot;);&lt;br /&gt;        myProcess.WaitForExit();&lt;br /&gt;        Trace.WriteLine(&quot; &quot; + DateTime.Now.ToString() + &quot; -- MSBuild Completed&quot;);&lt;br /&gt;        Trace.WriteLine(&quot; Process Completed: &quot; + myProcess.ExitCode.ToString());&lt;br /&gt;        return myProcess.ExitCode;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Here is the config file...its pretty self explanatory...&lt;br /&gt;&lt;br /&gt;&amp;lt;configuration&gt;&lt;br /&gt;  &amp;lt;appsettings&gt;&lt;br /&gt;    &amp;lt;add key=&quot;msbuild2005&quot; value=&quot;C:\windows\microsoft.NET\Framework\v2.0.50727\msbuild_old.exe&quot;&gt;&lt;br /&gt;    &amp;lt;add key=&quot;msbuild2008&quot; value=&quot;C:\windows\Microsoft.NET\Framework\v3.5\msbuild.exe&quot;&gt;&lt;br /&gt;    &amp;lt;add key=&quot;msbuild2008&quot; value=&quot;C:\windows\Microsoft.NET\Framework\v3.5\msbuild.exe&quot;&gt;&lt;br /&gt;    &amp;lt;add key=&quot;VisualStudio2008CompareString&quot; value=&quot;/p:SomeCustomSetting=Yes&quot;&gt;&lt;br /&gt;  &amp;lt;/appsettings&gt;&lt;br /&gt;&amp;lt;/configuration&gt;&lt;br /&gt;&lt;br /&gt;Hope that helps. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/04/tfs-2005-hack-for-building-visual.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-3480933242866968314</guid><pubDate>Mon, 31 Mar 2008 23:21:00 +0000</pubDate><atom:updated>2008-03-31T19:46:46.007-04:00</atom:updated><title>Get out your rusty pennies</title><description>I&#39;m going to piggy back of a fellow .NET gurus recent post about how worthless some of the Microsoft events I&#39;ve been to have been. By worthless, I mean, I was hoping I could get some girthy examples of technology I had been tinkering with, but felt as though I knew more than the presenter.&lt;br /&gt;&lt;br /&gt;You can read the initial, thought provoking, blog post by Keith Elder &lt;a href=&quot;http://keithelder.net/blog/archive/2008/03/31/.Net-War-Stories--TechEd-2008-Birds-of-a-Feather.aspx&quot;&gt;here&lt;/a&gt;. He mentions how it would be nice to have a round table to talk about &quot;real world&quot; examples of technologies MS offers like WF, WPF, Silverlight, etc (just read the article and you can follow along).&lt;br /&gt;&lt;br /&gt;Don&#39;t get me wrong, I usually do end up getting at least one thing out of MS events whether it be a LAUNCH event usually held in January in Detroit, or MS Evangelist presentations, or one on one discussions at work with the MS contacts we have. However, 9 times out of 10, I sometimes feel as though the examples are so HELLO WORLD that I actually know more about them than the person putting on the presentation.&lt;br /&gt;&lt;br /&gt;I know, I know. You&#39;re saying, &quot;Josh, those examples are supposed to ATTRACT people to the MS technologies. If you really wanted to learn, go read someone&#39;s blog.&quot; Well I don&#39;t know about you, but I am much more of a visual learner. I get way more out of a line of code than 2 hours of theory. First off, if its in code, I know it works, second off, most people aren&#39;t compilers. So usually when I try to do what they tell me to, I end up spending 3 times longer because the solution doesn&#39;t compile, or I heard down the wrong path because there wasn&#39;t clear enough communication, or whatever.&lt;br /&gt;&lt;br /&gt;So get to the damn point Josh.&lt;br /&gt;&lt;br /&gt;Alright, I really like Elder&#39;s idea of a roundtable with real world examples. However, F* the table. Let&#39;s create a site, where we can give real world examples, by real world I mean PRODUCTION real. Obviously we can&#39;t post custom code. But we can post our bug fixes, issues we found, &quot;I hate this technology&quot;, &quot;This worked great for me&quot;. Let&#39;s put it in one place.&lt;br /&gt;&lt;br /&gt;For example, here are some of my gripes, and praises.&lt;br /&gt;&lt;br /&gt;Windows Workflow Foundation&lt;br /&gt;Gripe 1: VS eats up 500MB of Ram when I open the designer -- usually hosing my computer at least once a day.&lt;br /&gt;Gripe 2: Setting up persistence is more than meets the eye. Start by reading my WF posts &lt;a href=&quot;http://flipstechnologyposts.blogspot.com/2007/10/windows-workflow-persistence-1-of.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;Gripe 3: Allowing only one runtime host out of the box for persistence stores is just poor.&lt;br /&gt;Gripe 4: Delay activities have a max delay time of 45 days due to the way it persists the delay activy timespan. Come on guys, do we test these applications?&lt;br /&gt;Gripe 5: Versioning can kick your ass.&lt;br /&gt;&lt;br /&gt;Praise 1: Wakeup timers are god&#39;s gift to development. No more writing your own wakeup app.&lt;br /&gt;Praise 2: Forces you to really abstract out the runtime engine and forces you to create &quot;wrapper&quot; static functions for interacting with the engine so you don&#39;t have duplicate code everywhere&lt;br /&gt;Praise 3: Gives a visual representation to something that may end up being pretty complicated.&lt;br /&gt;&lt;br /&gt;LINQ:&lt;br /&gt;Praise 1: Linq is freaking awesome. Yesterday I wrote a LINQ query that read all the checkboxes and a label from my rows in the gridview in ONE LINE OF CODE. No more creating a list to hold the labels, and then 2 foreach loops (1 for the gridviewrows, and 1 for the label list)&lt;br /&gt;&lt;br /&gt;ActiveRecord / NHibernate:&lt;br /&gt;Praise 1: great for quick application development&lt;br /&gt;Praise 2: great for getting your entire object graph&lt;br /&gt;&lt;br /&gt;Gripe 1: If not planned properly, can have SQL statements over 2 MB (yes, I&#39;ve seen them)&lt;br /&gt;Gripe 2: Without any forethought, doesn&#39;t force any sort of validation before saving. You should really derive all your objects from an IValidate so you have an IsValid() and some error list that are checked before saving your record to the DB&lt;br /&gt;Gripe 3: Currently has a Gotcha in your queries because they are string values. If you change a property name, you better have unit tests or you&#39;ll take one in the ass. With LINQ and LINQ to NHibernate, the querying is all at compile time.&lt;br /&gt;&lt;br /&gt;I don&#39;t know if this helps at all, but I think it really would be nice if someone put a site together that you could search for pros/cons/praises/gripes/gotchas for different technologies. I can&#39;t tell you how long I spent debugging the stupid DelayActivity persistence issue. At the time, there wasn&#39;t ANYTHING on the net that I could find. I finally just started putting random values until it failed, and then it was like Yep, thats why its failing.&lt;br /&gt;&lt;br /&gt;If you know of a site that has this info, let me know, I&#39;ll create my account now, and start putting my thoughts, examples, and experiences out there so with that, To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/03/get-out-your-rusty-pennies.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-4547111064971711399</guid><pubDate>Sun, 23 Mar 2008 23:09:00 +0000</pubDate><atom:updated>2008-03-23T19:28:21.642-04:00</atom:updated><title>Spoiled Rotten Brat</title><description>For the past few weeks I have been tinkering on a project that is going to utilize &lt;a href=&quot;http://www.adobe.com/devnet/flash/actionscript.html&quot;&gt;Adobe Flash&lt;/a&gt; and its AS3 programming language. I of course being so artistic, am not the lead Flash guru. I am simply using my object modeling experience to help convert the non-object oriented flash code to a much more object oriented approach.&lt;br /&gt;&lt;br /&gt;So this isn&#39;t about my knowledge of objects or how to object orient code, this post is about how spoiled I am as a Microsoft developer using Visual Studio. Everyday I create classes in VS2k8 and immediately I can instantiate that class, hit the period button, and voila, I get all my properties and XML comments. Man I&#39;m spoiled. I take this for granted, and sometimes I even complain because in ASP.NET webforms, there are times intellisense fails me (usually when binding in GridViews).&lt;br /&gt;&lt;br /&gt;Developing in AS3 is pretty easy. Easy meaning, its pretty much just a minor syntax change to C# and of course, learning the objects is quite difficult because I have never really used flash, but again, that is out of the scope of this post. What is in the scope, is how one goes about writing AS3. What I&#39;ve heard from other devleopers, and from a few blog posts I read online is to get out your favorite Text pad (ie: WordPad, &lt;a href=&quot;http://notepad-plus.sourceforge.net/uk/site.htm&quot;&gt;Notepad++&lt;/a&gt;, NotePad, ActionScript panel in Flash) and start coding.&lt;br /&gt;&lt;br /&gt;That&#39;s right, there is no flash intellisense. There is no XML comments. Spell it wrong, it won&#39;t run. No hints. I feel like I&#39;m back in my mainframe days working with C++ in college. It freaking sucks.&lt;br /&gt;&lt;br /&gt;The nice thing about Notepad++ is that it actually has built in color coding for ActionScript language. So for the keywords in flash (like Class, function, var, String, etc) it highlights the text as blue which is nice, but there is not CTRL + SPACE to auto complete your text.&lt;br /&gt;&lt;br /&gt;So the next time you are in Visual Studio, just be thankful you don&#39;t have to remember your entire object model, or class framework. We are all blessed to have such a great (and I&#39;ll admit buggy at times) tool like Visual Studio to develop with. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/03/spoiled-rotten-brat.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-3542223022554461129</guid><pubDate>Fri, 07 Mar 2008 10:34:00 +0000</pubDate><atom:updated>2008-03-07T06:25:53.740-05:00</atom:updated><title>Validation and AJAX</title><description>&lt;p&gt;Continuing my series of posts on how to create a basic website in ASP.NET, today I&#39;m going to talk about AJAX and Validation. I am not going to talk about all the options you have with AJAX, nor am I going to talk about, the at least 4 that I can think of off the top of my head, validators.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Basically I am going to talk about how to set them up in your newly created skeleton website we have been creating. I&#39;m sure if you&#39;ve been following along, you&#39;ve realized that there really aren&#39;t much guts to this website we have created so far, but it is a really good starting point. We haven&#39;t added any grids to display data or textboxes to retrieve it. We&#39;ve just set up a, what I believe to be solid, website skeleton.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What is AJAX?&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Well if you don&#39;t know what AJAX is by now, you probably are a WinForms developer or a newbie. Do a quick Google for &lt;a href=&quot;http://www.google.com/search?q=ajax&quot;&gt;AJAX&lt;/a&gt; and you&#39;ll find that AJAX is pretty much making a webpage act like a WinForm using JavaScript and XML.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Microsoft of two versions of its AJAX platform (or two sets of controls anyways) depending on if you are using &lt;a href=&quot;http://www.asp.net/ajax/ajaxcontroltoolkit/samples/&quot;&gt;.NET 2.0&lt;/a&gt; or &lt;a href=&quot;http://www.codeplex.com/Wiki/View.aspx?ProjectName=AtlasControlToolkit&quot;&gt;.NET 3.5&lt;/a&gt;. These two toolkits contains lots of awesome controls to make your web app look and feel like a WinForm giving your user a much better and faster experience. These two collections of controls are out of the scope of this post, so I&#39;m just going to leave it at that and let you play around on your own.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What is in the scope of this post is the UpdatePanel. Basically any ASynchronous postback (meaning when the user does something the page doesn&#39;t &quot;flicker&quot;) you want to wrap in an UpdatePanel. UpdatePanels give are the #1 easiest way to implement AJAX and make your application stop the page from FLICKERing on postbacks. If you want to read all the ins and outs of an UpdatePanel &lt;a href=&quot;http://www.asp.net/AJAX/Documentation/Live/overview/UpdatePanelOverview.aspx&quot;&gt;click here&lt;/a&gt;. I use UpdatePanels whenever I can in my applications, and to make things easy I usually put this in one of my master pages. DO NOT put an UpdatePanel inside your main master page (the one we created in the last post), and here is why. Some controls play old do not work in UpdatePanels like the &lt;a href=&quot;http://forums.asp.net/p/1024641/1512733.aspx#1512733&quot;&gt;FileUpload&lt;/a&gt;. I will always create a nested master page with my UpdatePanel on it that wraps the content placeholder. Here is a snippet.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;%@ Master Language=&quot;C#&quot; MasterPageFile=&quot;~/MasterPage.master&quot; AutoEventWireup=&quot;false&quot; CodeFile=&quot;MasterPage2.master.cs&quot; Inherits=&quot;MasterPage2&quot; %&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;asp:Content ID=&quot;Content1&quot; ContentPlaceHolderID=&quot;MasterPagePlaceHolder&quot; Runat=&quot;Server&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;asp:UpdatePanel runat=&quot;server&quot; ID=&quot;upUpdatePanel&quot;&gt;&lt;br /&gt;        &amp;lt;ContentTemplate&gt;&lt;br /&gt;            &amp;lt;asp:ContentPlaceHolder runat=&quot;server&quot; ID=&quot;MastPagePlaceHolder&quot; /&gt;&lt;br /&gt;        &amp;lt;/ContentTemplate&gt;&lt;br /&gt;    &amp;lt;/asp:UpdatePanel&gt;&lt;br /&gt;&amp;lt;/asp:Content&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Obviously this has some flaws, like if you need to add a Synchronous PostBack button, or something like that. In that case, use the base master page we created in the last post and add your own update panel. This master page is simply helping out our skeleton approach and adding us in not having the same code on every Page.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The ScriptManager&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;UpdatePanels are really sweet and all, but unless you add a ScriptManager to your page, you won&#39;t be able to compile. The &lt;a href=&quot;http://www.asp.net/AJAX/Documentation/Live/mref/T_System_Web_UI_ScriptManager.aspx&quot;&gt;ScriptManager&lt;/a&gt; is basically the brains of ASP.NET AJAX. It controls how the AJAX is handled as well as all the JavaScript needed to handle it. Adding the ScriptManager is a one liner that I always put on my base master page. This way I don&#39;t have to include the script manager on any pages, or user controls or nested master pages. I simply get the functionality I want right away for all pages. Here is the syntax for the ScriptManager.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;lt;asp:ScriptManager runat=&quot;server&quot; ID=&quot;smScriptManager&quot; AllowCustomErrorsRedirect=&quot;true&quot; OnAsyncPostBackError=&quot;smScriptManager_AsyncPostBackError&quot; /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And the error handler...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;    protected void smScriptManager_AsyncPostBackError(object o, AsyncPostBackErrorEventArgs args)&lt;br /&gt;    {&lt;br /&gt;        Utility.LogError(args.Exception);&lt;br /&gt;        Response.Redirect(&quot;~/ErrorPage.aspx&quot;);&lt;br /&gt;    }&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As you can see, the handler uses the Utility class we created in the previous post as well to write out the exception and then it does a redirect to our nicely formatted error page. If you don&#39;t do this, by default the ScriptManager displays a JavaScript alert box. If you don&#39;t do a Response.Redirect it will display the alert box, so you can handle it either way. I prefer to redirect them no matter what since 99% of the time they will just click whatever button caused them to error, which will most likely cause them to error again.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;AJAX Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Well that&#39;s pretty much all I know about AJAX that I feel is in the scope of this series of posts. Again, there are dozens of sweet AJAX controls (my favs being the CalendarExtender, UpdateProgress and Animation), but you will have to read and play with those on your own. The ScriptManager also has additional functionality like building the JavaScript classes needed to talk to a webservice directly in JavaScript, and some other stuff, but again, out of the scope. Basically, we simply create a new nested master page that wraps its content placeholder in an UpdatePanel which saves us some common code.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Validation&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;To start off, I am NOT going to talk about the different validation controls in ASP.NET. You should read this &lt;a href=&quot;http://www.4guysfromrolla.com/webtech/090200-1.shtml&quot;&gt;4Guys&lt;/a&gt; article which goes in depth about the different controls. What I am going to talk about is the ValidationSummary control.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The ValidationSummary control is used for displaying the collection of errors from your validators on your page to your user. This again, is similar to the UpdatePanel in that most pages will need to have one, so for consistency I again put this in my master page. I don&#39;t put it in its own master page though. I put it in the base master page. This way, any page that has fields on it, I can use any of my master pages, and automatically get the ValidationSummary built-in.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;How do you handle multiple &quot;validation sections?&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Innevitably, you&#39;ll have something that needs to validate on its own. Maybe a self contained usercontrol for displaying some information from a dropdown with its own Submit button and when the user enters an invalid date, you want the error to be right there in the control. ValidationSummarys have this property called ValidationGroup. The ValidationGroup is just that. A group of items to include with this Validation Summary. Basically when you click on the button (which also has a ValidationGroup property) it only runs the JavaScript for the validators with the same ValidationGroup name as the button that has been clicked. In this case you would have an infinite number of validation groups as long as all the validation controls reference the right group, you are good as gold.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;What if I want to display a custom message to the user thats not in a Validator?&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Good question. There are multiple things we need to do in that case. First is we need to add a label to our master page where we have added our ValidationSummary. I usually use the following snippet for that.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;lt;asp:Label runat=&quot;server&quot; id=&quot;lblError&quot; cssclass=&quot;Error&quot; /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Then I expose a method in my master page called SetError(string Error) and inside that method basically set the lblError.Text = Error; The easiest way to handle this is to add the MasterType tag to your page definition, or expose a method in your BasePage class that casts the this.Master property into your strongly typed base master page and calls the method. Either solution works, its just up to you.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another thing I expose is a Repeater which contains only a label. I expose a method called SetErrors(ICollection&lt;string&gt; Errors) and bind the errors to the Repeater. This way, I can display a list of errors instead of just a single error. This is handy when I am saving my business objects and I call bizObj.IsValid() and it returns false, then I can bind the errors to the repeater.&lt;p&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;I have to finish this up because its 6:30 and that&#39;s when my kid eats (he is 3 months old). Basically today we talked about adding the UpdatePanel, ScriptManager, and ValidationSummary our master pages and exposing some methods (SetError() and SetErrors()) which allow us to display error info to our users. Hope this is helping you better contstruct your sites. To the end, I shall go, but to the beginning is where I end up.&lt;/p&gt;</description><link>http://flipstechnologyposts.blogspot.com/2008/03/validation-and-ajax.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-3266204800549998117</guid><pubDate>Thu, 28 Feb 2008 23:26:00 +0000</pubDate><atom:updated>2008-02-28T18:45:13.960-05:00</atom:updated><title>Off Topic Post</title><description>I am going off topic for a quick post about some cool stuff I learned this week. Just some quick snippets I found very useful.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Writing out a binary file to XML and back again&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;I had a problem I was trying to solve the other day migrating app settings from environment to environment (local machine out to production). One of the settings was a table full of files (beit text, PDF, Word, Excel, etc) these needed to be migrated. I had already written an XML export and import (although not the most efficient I&#39;ll adming) and I needed to get these files in the XML file and back out again. Here is a really good post I found my answer.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.dotnet247.com/247reference/msgs/50/251476.aspx&quot;&gt;http://www.dotnet247.com/247reference/msgs/50/251476.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Props to the guy who thought of using Convert.ToBase64. Here is the code snippet I ended up with.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Export&lt;/h4&gt;&lt;br /&gt;docNode.SetAttribute(&quot;BinaryFile&quot;, fileByteArray != null ? Convert.ToBase64String(fileByteArray) : &quot;&quot;);&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Import&lt;/h4&gt;&lt;br /&gt;if (!string.IsNullOrEmpty(slNode.Attributes[&quot;BinaryFile&quot;].Value))&lt;br /&gt;{&lt;br /&gt;  fileByteArray = Convert.FromBase64String(slNode.Attributes[&quot;BinaryFile&quot;].Value);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Of course I won&#39;t go into the stream readers / writers to actually populate the byte arrays, but so far this works great. And the nice thing is the XML file isn&#39;t too bloated.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Using Reflection to load a UserControl in WinForms&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;First off, I&#39;m not a big WinForm developer. I spend most of my day in ASP.NET and SQL Mgt Studio so this was a big one for me. I know in ASP.NET you can dynamically load user controls as long as you know their reflected name from a string. So I thought, there has got to be a way to do this in WinForms. Of course, there is. Here is the snippet to dynamically load a user control from a type, and then add it to a panel inside of a WinForm app.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Assembly currentAssembly = Assembly.GetExecutingAssembly();&lt;br /&gt;Type controlToLoad = currentAssembly.GetType(&quot;Proj.NameSpace.MyUserControlTypeFullName&quot;);&lt;br /&gt;ConstructorInfo constructor = controlToLoad.GetConstructor(new Type[] { });&lt;br /&gt;UserControl cntrl = (UserControl)constructor.Invoke(null);&lt;br /&gt;cntrl.Dock = DockStyle.Fill;&lt;br /&gt;pnlUserControlHolder.Controls.Add(cntrl);&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Hope these two snippets help you out. I found them to be great. To the end, I shall go, but to the beginning is where I end up.&lt;/p&gt;</description><link>http://flipstechnologyposts.blogspot.com/2008/02/off-topic-post.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-6744776244543118367</guid><pubDate>Sat, 16 Feb 2008 14:36:00 +0000</pubDate><atom:updated>2008-02-16T10:36:40.281-05:00</atom:updated><title>Masterpages of the Universe</title><description>As a great superhero from the 80s would say, &quot;I have the power!!&quot;. Heman, the master of the universe is going to lead the discussion on master pages today. Actually he isn&#39;t, I am. Sorry, Heman will make an appearance later this year maybe.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So what is a master page??&lt;/h2&gt;&lt;br /&gt;When I think of a master page, I think of a wrapper page. Basically, the master page really shouldn&#39;t have any major logic in it. Master pages are like a skeleton. They are the bones of your website. The guts of course, are the pages themselves (and you could go on and on -- usercontrols are the organs, web controls are the blood vessels). Of course your pages do things like bind grids, allow data entry, etc, etc.&lt;br /&gt;&lt;br /&gt;The master page is an easy way to formalize the layout of your site. In the old ASP days, and even in the current PHP days, its common practice to put the first line of you code page as&lt;br /&gt;&amp;lt;include file=&quot;header/headerfile.asp&quot;&gt;&lt;br /&gt;which then prints out your CSS and your menu navigation system. Maybe some other random stuff as well. Same thing for a footer as well.&lt;br /&gt;&lt;br /&gt;So Josh, can&#39;t I just create user controls and do the same thing. Well sure, and you could pee in your gas tank too, but that really hinders the performance of your automobile doesn&#39;t it? Adding the same control on every page is a good idea. But what if you automatically got that functionality. That is what a master page is.&lt;br /&gt;&lt;br /&gt;The master page allows you to create your navigation and footer, in most cases, in one place. Then inside your actual page, you reference the master page, and voila. You automatically get the skeleton by adding about 30 characters to your guts page.&lt;br /&gt;&lt;br /&gt;Here is a code snippet for adding a master page.&lt;br /&gt;&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; MasterPageFile=&quot;~/MasterPages/BaseMaster.master&quot; CodeFile=&quot;Default.aspx.cs&quot; Inherits=&quot;_Default&quot; %&gt;&lt;br /&gt;&lt;br /&gt;The MasterPageFile attribute in the page declaration tells us where to get our master page. Another thing your page must include if it uses master pages is a Content tag. Your master page will have several (or at least one) ContentPlaceHolder tags which allow you to put your guts into your skeleton.&lt;br /&gt;&lt;br /&gt;More snippets&lt;br /&gt;Master Page Snippet&lt;br /&gt;&lt;br /&gt;&amp;lt;body&gt;&lt;br /&gt;    &amp;lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;    &amp;lt;div&gt;&lt;br /&gt;        &amp;lt;asp:contentplaceholder id=&quot;MasterPagePlaceHolder&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;   &amp;lt;/div&gt;&lt;br /&gt;   &amp;lt;/form&gt;&lt;br /&gt;&amp;lt;/body&gt;&lt;br /&gt;&lt;br /&gt;Page Snippet&lt;br /&gt;&amp;lt;asp:content contentplaceholderid=&quot;MasterPagePlaceHolder&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;   The Guts -- all your controls&lt;br /&gt;&amp;lt;/asp:Content&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So what is this going to do??&lt;/h2&gt;&lt;br /&gt;If you take a deep look at what a master page actually is, its really just a sophisticated page in and of itself. So ASP.NET treats it as such when it renders itself. It calls the Page_Load, Page_Init and renders all of the child controls. It just so happens that the child controls point to pages which then render themselves.&lt;br /&gt;&lt;br /&gt;So I&#39;ll give you a real world working example of a master page and a content page. This will show you what I&#39;m talking about.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Master Page&lt;br /&gt;&amp;lt;%@ Master Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeFile=&quot;MasterPage.master.cs&quot; Inherits=&quot;MasterPage&quot; %&gt;&lt;br /&gt;&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;&amp;lt;head runat=&quot;server&quot;&gt;&lt;br /&gt;    &amp;lt;title&gt;Master Page&amp;lt;/title&gt;&lt;br /&gt;&amp;lt;/head&gt;&lt;br /&gt;&amp;lt;body&gt;&lt;br /&gt;    &amp;lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;    &amp;lt;div&gt;&lt;br /&gt;        &amp;lt;div&gt;&lt;br /&gt;            Welcome to Josh&#39;s Custom Site&lt;br /&gt;        &amp;lt;/div&gt;&lt;br /&gt;        &amp;lt;div&gt;&lt;br /&gt;            &amp;lt;asp:sitemappath id=&quot;SiteMapPath1&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;            &amp;lt;/asp:SiteMapPath&gt;&lt;br /&gt;        &amp;lt;/div&gt;&lt;br /&gt;        &amp;lt;hr /&gt;&lt;br /&gt;        &amp;lt;div&gt;&lt;br /&gt;            &amp;lt;asp:menu id=&quot;Menu1&quot; runat=&quot;server&quot; datasourceid=&quot;SiteMapDataSource1&quot; orientation=&quot;Horizontal&quot;&gt;&lt;br /&gt;            &amp;lt;/asp:Menu&gt;&lt;br /&gt;            &amp;lt;asp:sitemapdatasource id=&quot;SiteMapDataSource1&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;        &amp;lt;/div&gt;&lt;br /&gt;        &amp;lt;div&gt;&lt;br /&gt;            &amp;lt;asp:contentplaceholder id=&quot;MasterPagePlaceHolder&quot; runat=&quot;server&quot;&gt;&lt;br /&gt;        &amp;lt;/div&gt;&lt;br /&gt;        &amp;lt;div&gt;&lt;br /&gt;            &amp;lt;hr /&gt;&lt;br /&gt;            &amp;lt;center&gt;&lt;br /&gt;                Copyright, Josh Springer, February 16, 2008&lt;br /&gt;            &amp;lt;/center&gt;&lt;br /&gt;        &amp;lt;/div&gt;&lt;br /&gt;    &amp;lt;/div&gt;&lt;br /&gt;    &amp;lt;/form&gt;&lt;br /&gt;&amp;lt;/body&gt;&lt;br /&gt;&amp;lt;/html&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Page Code&lt;br /&gt;&amp;lt;%@ Page Language=&quot;C#&quot; MasterPageFile=&quot;~/MasterPage.master&quot; AutoEventWireup=&quot;true&quot; CodeFile=&quot;FirstPage.aspx.cs&quot; Inherits=&quot;FirstPage&quot; Title=&quot;Untitled Page&quot; %&gt;&lt;br /&gt;&amp;lt;%@ MasterType VirtualPath=&quot;~/MasterPage.master&quot; %&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;asp:content id=&quot;Content1&quot; contentplaceholderid=&quot;MasterPagePlaceHolder&quot; runat=&quot;Server&quot;&gt;&lt;br /&gt;    My Custom Book List&lt;br /&gt;    &amp;lt;asp:repeater runat=&quot;server&quot; id=&quot;CustomBookRptr&quot;&gt;&lt;br /&gt;        &amp;lt;itemtemplate&gt;&lt;br /&gt;            &amp;lt;%# Eval(&quot;BookId&quot;) %&gt; -- &amp;lt;%# Eval(&quot;BookTitle&quot;) %&gt;&lt;br /&gt;        &amp;lt;/itemtemplate&gt;&lt;br /&gt;    &amp;lt;/asp:Repeater&gt;&lt;br /&gt;&amp;lt;/asp:Content&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What does this render??&lt;/h2&gt;&lt;br /&gt;Well you have to assume that I created a simple IList&amp;lt;T&gt; of a custom object in the page itself, then bind that list to the repeater. I could have done a DB read, LINQ Query, etc. Use your imagination.&lt;br /&gt;&lt;br /&gt;Now as the ASP.NET is rendering your actual page, it realizes that you have a master page to be rendered (from the MasterPageFile) tag. It then knows to go and render that first. So as our markup suggests, it builds out a main header, a sitemap path which is basically a breadcrumb telling the user where they are in the hierarchy of pages, and a menu. So as you can tell, any page that references this master page will look similar and have navigation, a main body header, and a breadcrumb.&lt;br /&gt;&lt;br /&gt;It then continues render your page, so in this case, it will spit out the rendered repeater with all the book numbers and their titles.&lt;br /&gt;&lt;br /&gt;Finally, it renders our simple copyright footer. You could again have another navigation structure which allows the user to navigate to all pages as links instead of a navigation menu. Or you could just not have a footer.&lt;br /&gt;&lt;br /&gt;As you can see, master pages are pretty sweet. They make common page layouts very simple to accomplish. They also make a one stop shop for any changes to the main page layout. So lets say I wanted to have a treeview navigation now, instead of a menu system like I have. I could simply create a table, add a column and put my treeview in it, then add a second column and put my ContentPlaceHolder which would contain my main page content.&lt;br /&gt;&lt;br /&gt;Another cool thing with master pages is the MasterType declaration which will actually strongly type your master page. Giving you access to any methods, or properties on the master page. I&#39;ll go a little further in my next paragraph.&lt;br /&gt;&lt;br /&gt;So Josh, I see how cool they are, now what else can a Master Page do for me?&lt;br /&gt;Well, going back to my previous article about creating a custom base page to get some common function. One thing that my base master page has is an &amp;lt;asp:label id=&quot;ErrorLbl&quot;&gt;. Of course there are going to be times where something happens that I want to relay a message back to the user. So instead of creating this label on ALL of my pages, I put it on my master page. I also put a repeater on my master page as well, in case I want to put a LIST of error messages up. Both of these are styled according to how I want my errors to display (usually CssClass=&quot;Error&quot;).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How do I set the label or the repeater?&lt;/h2&gt;&lt;br /&gt;I don&#39;t directly expose these controls as that would just not be good. If I wanted to replace them, I couldn&#39;t. So I abstract them out by exposing the following methods:&lt;br /&gt;&lt;br /&gt;public void SetError(string Error) { lblError.Text = Error; }&lt;br /&gt;public void SetErrors(ICollection Errors) { rptrErrors.DataSource = Errors; rptrErrors.DataBind(); }&lt;br /&gt;&lt;br /&gt;Now I&#39;m sure I can improve on these, like just exposing a set errors and keeping a collection internally and then rebinding in the Render() method. But I really haven&#39;t come across a scenario where these two cases don&#39;t fit.&lt;br /&gt;&lt;br /&gt;NOTE: if you go this route, you will need to clear out the errors in the Page_Load of the master page so you don&#39;t keep unneeded errors around.&lt;br /&gt;&lt;br /&gt;In the master page...&lt;br /&gt;void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;     lblError.Text = &quot;&quot;;&lt;br /&gt;     rptrErrors.DataSource = null;&lt;br /&gt;     rptrErrors.DataBind();&lt;br /&gt;&lt;br /&gt;    if (!PostBack) { //do initial loading code if any }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now how do you actually talk to your master page from the Page itself. That gets to the MasterType declaration we made in the page. What this does is strongly type the [this.Master] property inside the page to your custom master page type. Once that happens, you can access the master pages properties / methods / etc as long as they are exposed in the master page.&lt;br /&gt;&lt;br /&gt;Page Snippet....&lt;br /&gt;if (!txtTest.Text == &quot;I am right&quot;)&lt;br /&gt;    this.Master.SetError(&quot;Invalid answer to the Test question&quot;);&lt;br /&gt;&lt;br /&gt;if (!myObj.IsValid())&lt;br /&gt;    this.Master.SetErrors(myObj.ErrorMessages);&lt;br /&gt;&lt;br /&gt;Pretty cool eh??&lt;br /&gt;&lt;br /&gt;What other cool stuff could I put on my master page??&lt;br /&gt;Another common thing I usually put on my master page is a ValidationSummary with NO validation group. This gives me a common place for all my error messages, and saves me from having to add one to all my entry pages. For any custom validation (like a user control 0r something), I would simply add a validation summary directly to that page/control and give it a validation group so it won&#39;t fire off the validation from the master page.&lt;br /&gt;&lt;br /&gt;I also put an &amp;lt;asp:scriptmanager&gt; tag on my master page to get all of the AJAX enabled stuff. Again, this just saves me from putting it on every single page. I&#39;ll talk more about AJAX in my next post.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So what did we just talk about??&lt;/h2&gt;&lt;br /&gt;Well, I explained that a master page is very similar to the old &amp;lt;include&gt; tag in ASP and PHP except that instead of adding the &amp;lt;include&gt; tag to your page, you simple add the MasterPageFile attribute to the page declaration. Master pages are an extremely good way of getting common page layouts accross your entire site, as well as encapsulating common things like lblError and rptrErrors and the ScriptManager that most pages need into a single, common place.&lt;br /&gt;&lt;br /&gt;Here are some good links about master pages. 4Guys has a series on creating and using master pages. If you want to dig deep, I highly recommend it.&lt;br /&gt;&lt;br /&gt;MSDN: &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/wtxbf3hh.aspx&quot;&gt;http://msdn2.microsoft.com/en-us/library/wtxbf3hh.aspx&lt;/a&gt;&lt;br /&gt;4Guys: &lt;a href=&quot;http://aspnet.4guysfromrolla.com/articles/010505-1.aspx&quot;&gt;http://aspnet.4guysfromrolla.com/articles/010505-1.aspx&lt;/a&gt; and &lt;a href=&quot;http://aspnet.4guysfromrolla.com/articles/013107-1.aspx&quot;&gt;http://aspnet.4guysfromrolla.com/articles/013107-1.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once again, if you have questions, or think I can improve in any way, feel free to comment. Hope this helped. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/02/masterpages-of-universe.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-3217098365478917499</guid><pubDate>Wed, 13 Feb 2008 11:49:00 +0000</pubDate><atom:updated>2008-02-13T07:00:47.539-05:00</atom:updated><title>Associated Links to my first Post</title><description>Sorry I didn&#39;t include any of these links in last nights post. The baby started to fuss, and I wanted to see him before he went to bed.&lt;br /&gt;&lt;br /&gt;ASP.NET Membership How To -- &lt;a href=&quot;http://aspnet.4guysfromrolla.com/articles/120705-1.aspx&quot;&gt;http://aspnet.4guysfromrolla.com/articles/120705-1.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;log4net -- &lt;a href=&quot;http://logging.apache.org/log4net/download.html&quot;&gt;http://logging.apache.org/log4net/download.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enterprise Library Exception Block -- &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa480461.aspx&quot;&gt;http://msdn2.microsoft.com/en-us/library/aa480461.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Customer Errors in the web.config file -- &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/h0hfz6fc%28VS.71%29.aspx&quot;&gt;http://msdn2.microsoft.com/en-us/library/h0hfz6fc(VS.71).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you plan on using ASP.NET forms authentication you should definitely read the 4guys article above. It is a 9 part series that walks you through everything.</description><link>http://flipstechnologyposts.blogspot.com/2008/02/associated-links-to-my-first-post.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-4692021986333383040</guid><pubDate>Wed, 13 Feb 2008 00:11:00 +0000</pubDate><atom:updated>2008-02-12T20:29:47.991-05:00</atom:updated><title>Setting up a Basic Web Application in ASP.NET</title><description>&lt;p&gt;Today a novice .NET co-worker of mine asked me a really good question that in turn leaded to several other good questions, &quot;How do you handle errors in ASP.NET?&quot; Of course, that then lead into the Page_Error and Application_Error, but I really wanted to dig deep so I started explaining how I start new web applications.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I plan on writing a short series on my opinion on web application development starting with some basic principles for web applications, moving on to master pages, then discussing validation and ajax, finally and web services. I won&#39;t cover user management using the ASP.NET Forms Authentication or Active Directory Authentication as those are out of the scope of this series.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This article will cover some basic principles for web applications such as error handling and using a custom base page.&lt;/p&gt;&lt;br /&gt;&lt;H2&gt;Error Handling&lt;/H2&gt;&lt;br /&gt;&lt;p&gt;Of course we all write perfect code that never throws exceptions, so there is no need for this topic to be covered. So I&#39;ll just skip it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;YEAH RIGHT!!&lt;/b&gt; Error handling is something you need to think about briefly, implement once, and somewhat forget about. Error handling in web applications is handled in two major ways. The first, is in an overall Application error handling. Adding error handling on the Application level can be done by adding an Application_Error() method to the Global.asax file. This is a good catch&#39;all for error handling. Just an FYI, this can handle some unneeded exceptions like 404 errors, 401 errors, as well as thread &quot;stops&quot; which are usually done when you do a Response.WriteFile() or Response.Close() inside your page. This is not really an exception, but IIS and ASP.NET treat it as such. Here is a snippet of handling exceptions on the Application level.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;void Application_Error(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;   Exception lastException = Server.GetLastError();&lt;br /&gt;   Server.ClearError();&lt;br /&gt;   Utility.HandleException(lastException); //I&#39;ll cover this later on in this post.&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;Congratulations, you have successfully handled ALL exceptions in your application. However, you aren&#39;t redirecting anywhere, and the user still gets the awesome ASP.NET Server Error page. You could easily add a Response.Redirect(&quot;somedefaulterrorpage.html&quot;); if you wanted, but for errors like 404s, or something you may want to do that differently. For this you can use the web.config to handle custom errors to redirect the user to a custom error page.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The second type of error handling is the Page level error handling. This is done via the Page_Error event handler. I highly recommend you do error handling on a page level instead of an application level. This allows you to add any custom data to your exception like current user, maybe some data fields from the screen, things from Session your page knows about, etc. I&#39;ll cover this more in my base page explanation, but first a quick code snippet.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;void Page_Error(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;   Exception lastException = Server.GetLastError();&lt;br /&gt;   Server.ClearError();  // if you don&#39;t call this method, your Application_Error will also handle this exception.&lt;br /&gt;&lt;br /&gt;   //Adding custom information to an exception can be done using the Dictionary&lt;br /&gt;   //DATA property on the exception. You can then interpret this info to help for&lt;br /&gt;   //debugging.&lt;br /&gt;   lastException.Data.Add(&quot;URL&quot;, Request.Url);&lt;br /&gt;   lastException.Data.Add(&quot;SomeTextField&quot;, txtMyTextField.Text);&lt;br /&gt;&lt;br /&gt;   Utility.LogError(lastException);&lt;br /&gt;   Response.Redirect(&quot;~/mycustomerrorpage.html&quot;); //Always let the user know something bad happened with a nice message&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Again, you should always implement one or both of these error handling options. If you don&#39;t have some sort of error handling in your application, your users will become frustrated when your app doesn&#39;t work right and they don&#39;t get any message saying such. They just get the great 500 Internal Server error. Or better yet, they&#39;ll get your entire stack trace. You should also try and wrap complex logic in a Try/Catch method as well. Its always better to display a helpful error message to the user than just redirecting to an error page. Something a Try/Catch might be good for is casting a text field into an integer or something like that. &lt;/p&gt;&lt;br /&gt;&lt;H2&gt;Custom Base Page&lt;/H2&gt;&lt;br /&gt;&lt;p&gt;Creating your own custom base page that inherits from System.Web.UI.Page is probably something many people don&#39;t really think is a necessity. However, this is probably one of the more important things I find in development of a solid web application. The custom base page should do several things. First it should create a wrapper property which enables all derived pages to access your Custom Business Object which represents your user. Whether that be ASP.NET Forms Authentication User or an Active Directory User, or some other custom user. This is a requirement because 99 out of 100 times you will either display the logged on user information to your pages, or you will use the logged on user as a &quot;last updated by&quot; on your DB records. Here is a quick snippet of what I am talking about.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;private CustomBusinessUserObject _CurrentLoggedOnCustomBusinessUserObject = null;&lt;br /&gt;protected CustomBusinessUserObject CurrentLoggedOnCustomBusinessUserObject&lt;br /&gt;{&lt;br /&gt;   if (_CurrentLoggedOnCustomBusinessUserObject == null)&lt;br /&gt;   {&lt;br /&gt;      //Look up custom business user. usually using this.User.Identity.Name;&lt;br /&gt;      //_CurrentLoggedOnCustomBusinessUserObject = GetCustomUser();&lt;br /&gt;   }&lt;br /&gt;   return _CurrentLoggedOnCustomBusinessUserObject;&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You could also store the CurrentLoggedOnCustomBusinessUserObject into either the Session or the Cache objects of the page. If you plan on storing the object in the Session or Cache you must make sure your object is marked as [Serializable()]. Please be aware that storing your object in something like Session / Cache you could run into stale data where your DB has change so your user may not have the same information as your CurrentLoggedOnCustomBusinessUserObject object, so you will definitely want to be aware of this.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Piggy backing on my error handling, your base page should also implement custom error handling. This way you don&#39;t have the same code on every single page. Now you are asking, well how do I get custom data into the exception if I&#39;m handling it on a base page. You use virtual methods of course. You might want to add a AddCustomDataToException(Exception HandledException) method which allows you to do that. Here is a quick snippet.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;h3&gt;Base Page Implementation&lt;/h3&gt;&lt;br /&gt;protected virtual void AddCustomDataToException(Exception HandledException)&lt;br /&gt;{&lt;br /&gt;   //add nothing in the base page. This is simply used so the derived pages can &lt;br /&gt;   //add data to the exception.&lt;br /&gt;}&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Derived Page Implementation&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;protected override void AddCustomDataToException(Exception HandledException)&lt;br /&gt;{&lt;br /&gt;   HandledException.Data.Add(&quot;MyCustomViewStateProperty&quot;, this.MyCustomViewStateProperty);&lt;br /&gt;   HandledException.Data.Add(&quot;MyCustomSessionProperty&quot;, this.MyCustomSessionProperty);&lt;br /&gt;   HandledException.Data.Add(&quot;txtTextBox&quot;, txtTextBox.Text);&lt;br /&gt;}&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Base Page Error Handling Snippet&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;void Page_Error(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;   Exception lastException = Server.GetLastError();&lt;br /&gt;   Server.ClearError();&lt;br /&gt;   lastException.Data.Add(&quot;URL&quot;, Request.Url);&lt;br /&gt;   lastException.Data.Add(&quot;MyCustomBusinessObjectCurrentUser&quot;, _CurrentLoggedOnCustomBusinessUserObject != null ? CurrentLoggedOnCustomBusinessUserObject.PrimaryKeyIdentifier : &quot;No User Info&quot;);&lt;br /&gt;   this.AddCustomDataToException(lastException);&lt;br /&gt;   Utility.LogError(lastException);&lt;br /&gt;   Response.Redirect(&quot;~/mycustomerrorpage.html&quot;);&lt;br /&gt;}&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Utility Static Class&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;The last thing that your website should have as a basic building block is a static utility class. I use this class for lots of things. Obviously, I have been referencing the LogError() method which handles errors. Again, there are umpteen ways of handling exceptions. You can use log4net, Microsoft Enterprise Library, just sending an email using the MailMessage object, inserting records in a DB, I could go on and on. The implementation is out of the scope of this post. So I&#39;ll leave that up to you.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another thing you might want in your utility class is handling caching, or reading data from your web.config file. I just recently started using the utility class for the web.config settings. I saw a co-worker do this in their business layer of their project (which is another good place for it), and thought, gee, why didn&#39;t I think of that. Basically what you do, is create static read only string properties that wrap your web.config settings so you don&#39;t have STRINGS all over your application. You&#39;re thinking, NOW I GET IT!!! Here is a snippet.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Old Way&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;string mySetting = System.Configuration.ConfigurationManager.AppSettings[&quot;mySetting&quot;];&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;h3&gt;New Way&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;public static string MySetting&lt;br /&gt;{&lt;br /&gt;   get { return System.Configuration.ConfigurationManager.AppSettings[&quot;mySetting&quot;]; }&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This type of implementation does two things for us. One, it gets rid of STRINGS everywhere in our web app. This is great because we can now replace the web.config setting with something from a DB, or other external data store. Second, and probably most important, it now tells us EVERYWHERE that the setting is used. So if someone changes the name of the property, the app will stop compiling, instead of getting runtime errors, we&#39;ll get compile time errors which everyone will agree are Much Much Much better.&lt;/p&gt;&lt;br /&gt;&lt;H2&gt;Conclusion&lt;/H2&gt;&lt;br /&gt;&lt;p&gt;Over the past several paragraphs, and probably 30 minutes or so of your reading, I have discussed some common topics like error handling in the Application using Application_Error and on the Page level using the Page_Error as well as creating a custom base page which automatically gives us error handling on all pages. I also touched on a utility static class that gives us some basic methods and properties for reading the config file and doing some common functions. To the end, I shall go, but to the beginning is where I end up.&lt;/p&gt;</description><link>http://flipstechnologyposts.blogspot.com/2008/02/setting-up-basic-web-application-in.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-5496018591885472937</guid><pubDate>Thu, 31 Jan 2008 19:59:00 +0000</pubDate><atom:updated>2008-01-31T15:11:19.856-05:00</atom:updated><title>Reading a CSV with ease</title><description>Yesterday I had to write a quick WinForms app that read in a CSV file and spun through the records looking for a specific column and performing some action on said column. Now I had previously done something similar with an uploaded file in a WebForms app, so I figured I&#39;d steal the code. Now I&#39;m going to share it with you. Just because I&#39;m such a nice guy.&lt;br /&gt;&lt;br /&gt;I&#39;m going to go out on a limb and assume you can get to the CSV file using either an upload control or you know the file path using the OpenDialog Window in WinForms.&lt;br /&gt;&lt;br /&gt;First &quot;connect&quot; to the CSV file...&lt;br /&gt;string ConnectionString = @&quot;Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=&quot; + System.IO.Path.GetDirectoryName(CSVFileName) + &quot;;Extensions=csv;&quot;;&lt;br /&gt;&lt;br /&gt;// Create an ODBC connection Obj&lt;br /&gt;System.Data.Odbc.OdbcConnection TextConnection = new System.Data.Odbc.OdbcConnection(ConnectionString);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next open the file using the connection...&lt;br /&gt;TextConnection.Open();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then run a &quot;SELECT&quot; statement against it&lt;br /&gt;System.Data.Odbc.OdbcDataAdapter da = new System.Data.Odbc.OdbcDataAdapter(&quot;select * from [&quot; + System.IO.Path.GetFileName(CSVFileName) + &quot;]&quot;, TextConnection);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally populate a dataset with the file info...&lt;br /&gt;DataSet records = new DataSet();&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;   // Fill the dataset with the adapter and give it a table name&lt;br /&gt;   da.Fill(records, &quot;Table Name&quot;);&lt;br /&gt;   TextConnection.Close();&lt;br /&gt;   da.Dispose();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now you have a dataset populated with your data from the CSV. Of course you can create a strongly typed dataset which will force your CSV to conform to a specific schema. For my project, I was passing in the names of the columns I needed from an XML file so I just used a plain Jane dataset.&lt;br /&gt;&lt;br /&gt;Overall I find this extremely handy. Once you get the dataset you can then use the underlying datatables to run quazi-select statements to actually limit the data you want returned. Here is an example.&lt;br /&gt;&lt;br /&gt;ds.Tables[&quot;Table Name&quot;].Select(&quot;ColumnName = &#39;SomeValue&#39;&quot;)&lt;br /&gt;ds.Tables[&quot;Table Name&quot;].Select(&quot;ColumnName IN (1, 2, 3, 4, 5)&quot;)&lt;br /&gt;&lt;br /&gt;Well that&#39;s pretty much it. I hope you enjoyed this as much as I have. Feel free to let me know if you know of any easier / better / more efficient ways to do something like this. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/reading-csv-with-ease.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-6757186225825456782</guid><pubDate>Fri, 25 Jan 2008 01:30:00 +0000</pubDate><atom:updated>2008-01-24T20:45:57.948-05:00</atom:updated><title>To ReadOnlyList or to ReadOnlyChild</title><description>Well this week I finally started development using CSLA. One of my co-workers found a &lt;a href=&quot;http://www.codesmithtools.com/&quot;&gt;CodeSmith&lt;/a&gt; template for CSLA which uses an XML document to parse through and built out objects. So after spending 2 days trying to understand code smith and finally getting XML comments added to the template with some customization I started generating the code for my actual business objects. Now first and foremost, I am in no way an expert in CSLA or code smith so I am struggling through both. So I was totally unsure how to construct my CSLA object model. I knew how I wanted to construct my NORMAL object model with lookup tables, and static manager classes as well as my normal business objects with their logic as well. Now, how do I convert my understanding of an object model to CSLA and its set of BusinessBase objects. Now, I kind of knew that you only want to use Root objects when you need to retrieve a specific object by its primary key, which is something I needed to do for my lookup tables, but I also knew that I could easily build a cache around these objects as well so there would be some manager class in charge of them. Well after discussing the situation with the aforementioned co-worker, I made the decision that he suggested and that was to use ReadOnlyChild as the actual object, and ReadOnlyRootList as the &quot;manager.&quot; On the &quot;manager&quot; I could create several methods to retrieve all the items, or only a specific item, or what not. This totally makes sense once you think about it. However, when I looked in the CSLA book, I couldn&#39;t really find any right or wrong way to handle a situation like this. CSLA implementation so far is very difficult for me to grasp. It is a total shift from things I have been doing in the past. Especially when ALL the initial code is automatically implemented for me because of the code smith templates. Now, I really don&#39;t know the entire reason why I am doing what I am doing, so I&#39;m hoping this weekend I can go back over the book this weekend and actually see WHY I need to use these two objects. Well, thats it for this short, non-informative post. I just wanted to let everyone who reads this that I am still alive and coding. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/to-readonlylist-or-to-readonlychild.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-4444492659806820212</guid><pubDate>Tue, 15 Jan 2008 23:32:00 +0000</pubDate><atom:updated>2008-01-15T20:32:55.635-05:00</atom:updated><title>Reading just doesn&#39;t do it</title><description>Well, this weekend I spent a crapton of time reading the CSLA book by &lt;a href=&quot;http://www.lhotka.net/&quot;&gt;Rocky Lohtka&lt;/a&gt; called Expert C# 2005 Business Objects. It talks completely about CSLA and how to develop scalable enterprise applications. So far I think there are some good things that you get right out of the box like automatic data validation before saving the data. You also get a SMALL object graph (basically parent / child). You also get built in Read/Write verification for you properties on your object, so that people who attempt to update the data that don&#39;t have access to update it will error. It also uses a small rules engine for validating its data using delegates so no matter how you call SAVE() these rules are executed and if the object is invalid it will not save itself or its children (assuming the record is a parent). Everything I have read about so far seems like we might need more objects in the new CSLA infrastructure versus its implementation using &lt;a href=&quot;http://www.nhibernate.org&quot;&gt;Nhibernate&lt;/a&gt;, however, you also get some base functionality you didn&#39;t have with straight NHibernate. It looks like we might need custom objects for any special queries that we write, but I&#39;m not quite sure on this yet because I haven&#39;t actually written any code yet. I also think it will be quite the paradigm shift with how I think about objects. The book mentions that you must stop looking at your objects relationally, and start looking at them as pieces of functionality. I think this relates to grouping objects by behavior versus what they actually store. Rocky mentions that the having the same data fields in multiple places isn&#39;t as big a stink as having duplicate LOGIC, or pieces of logic all over resulting in spaghetti code as he puts it. Well back to reading for me. I am finally getting into chapter 8 which implements his sample application. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/reading-just-doesnt-do-it.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-2306458547610799101</guid><pubDate>Fri, 11 Jan 2008 14:47:00 +0000</pubDate><atom:updated>2008-01-11T09:55:15.229-05:00</atom:updated><title>Step 3: Start Using CSLA</title><description>&lt;a href=&quot;http://www.lhotka.net/cslanet/&quot;&gt;CSLA&lt;/a&gt; it is...This week I am starting a CSLA project to determine whether it is a viable option for system development. From this point on, most of my posts will focus mainly on the ins and outs of CSLA and a solid comparison to NHibernate and how the two are similar / different. I haven&#39;t really started USING CSLA yet, but I have started stubbing out my basic methods I&#39;ll need for validation and custom logic that most objects need like CanUserDoThis(), TakeThisAction() and the like. Also started rewriting my AbstractUnitTestBase class which helps me get some common functionality in my unit tests like GetDefaultUser(), get random values, and create transactions for true DB testing. Not sure yet how I will create the transaction, but I&#39;m doing some reading this weekend to see how CSLA works so hopefully I&#39;ll get a grasp of it. However, the first thing I did notice, is that the object graph is gone. With &lt;a href=&quot;http://www.nhibernate.org&quot;&gt;Nhibernate&lt;/a&gt; you get this great object graph you can easily traverse, change and flush. So far, CSLA doesn&#39;t match nicely with this pattern. However, it does require a little more object thought. No more IList&lt;MyType&gt; MyTypes. It appears you have a custom MyTypeCollection that does all the reading and writing. Which is good to have that super control, but adds another class, and breaks the ability to navigate the object graph. Anyways, more to come. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/step-3-start-using-csla.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-747561385654373723</guid><pubDate>Wed, 09 Jan 2008 03:49:00 +0000</pubDate><atom:updated>2008-01-08T23:03:10.653-05:00</atom:updated><title>Step 2: Deciding on a Data Access Standard</title><description>Well today we decided as a company to adopt LINQ to SQL and the MS Entities Framework as well using stored procs for our data access. I guess this is a good idea. Kind of sucks that the apps I have worked on in the past few months are going to be out dated and require a rewrite (at least a quasi rewrite anyways). So that leads me to step 2 of creating a new application framework which is determining how data access should be handled. Some of the new things we are going to have to consider is how to maintain the LINQ DataContext objects which contain all your DB objects so LINQ can talk to the DB. Another challenge we are going to have is coming up with a standard and easy way to get some basic functionality out of our objects like Save(), Find(), Delete() that we got out of the box with ActiveRecord. Now mind you, they aren&#39;t anything super fancy, a simple LINQ query for FIND() is:&lt;br /&gt;&lt;br /&gt;var obj = From dataContext.Table.FirstOrDefault(o =&gt; o.PrimaryKeyField == VALUE);&lt;br /&gt;return obj as MyObject;&lt;br /&gt;&lt;br /&gt;You probably don&#39;t even need the specific cast, but you might want to ensure it anyways. Your delete is very similar, but with any update in LINQ you have to tell the DataContext that something is/has changed. Which leads me to my next point, of maintaining some sort of static DataContext somewhere, or passing an instance of it all over the place. Similar to how AR and NH have Scopes and ISession which are usually maintained in the User&#39;s Session or a static variable in a WinForm / Console app, we will now have to manage that object so you can perform an update on a set of objects instead of performing a set of updates on individual objects. The other possible solution is somewhat database intensive in that you would update each object as its own instance, and you wouldn&#39;t worry about updating 40 objects and FLUSHing one time. You would flush once for each individual object.&lt;br /&gt;&lt;br /&gt;As you can see, there are a lot of considerations when talking about migrating away from one data access framework to another. Even if we went towards a completely stored procedure approach you have similar problems whereas the application has to maintain it&#39;s own object &quot;dirtyness&quot;. And then you really don&#39;t get the whole SESSION / SCOPE approach where you can Save() dozens of objects, but wait until the end to actually FLUSH those changes to the DB. Anyways, it will be a challenge to see what we come up with, but I am confident that with my team members we will come up with a valuable, easy to use, easy to understand approach that is also easy to implement and maintain. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/step-2-deciding-on-data-access-standard.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-7588800050747114607</guid><pubDate>Sat, 05 Jan 2008 15:02:00 +0000</pubDate><atom:updated>2008-01-05T10:31:56.824-05:00</atom:updated><title>CSLA Analysis &amp; my lead up to our own framework</title><description>First off, sorry for the length of this post. I know I posted a few weeks, or maybe months ago now, about taking a look at CLSA. Well, after watching several of Rocky&#39;s videos on .NET Rocks TV, and speaking with a fellow developer who is actually attempting to use CSLA on a new project, I have come to the conclusion that is really doesn&#39;t save you much when it comes to web development. After several meetings with other senior level developers at my place of work, it has been quasi-decided that CSLA is going to be our framework of choice. Here are a list of the few pluses that they have identified so far. First and foremost are the mobile objects which means you simply change a configuration file (which by the way I am not a fan of) and your business logic in your objects now runs on an app server versus the client machine. For winforms apps, obviously MAJOR plus. Especially if you start to think about caching and super intense processes that could eat up the client machine but take no time on a server farm. The other major plus you get out of CSLA is a standard way of coding. By this I don&#39;t mean it has its own compiler warning rules that if you don&#39;t put all your IF statement logic on each individual line the compile will fail. I mean that ALL classes have a basic structure to them. They all have identical methods for fetching, saving and deleting data into your data store. Another bonus is that it has its own method of validation both rule validation as well as CanRead / CanWrite validation. So if you are truly worried that Joe Smoe shouldn&#39;t be READING properties of your object, CSLA takes care of this with a little piece of code in the GETTER and SETTER similar to this:&lt;br /&gt;&lt;br /&gt;public int SomeInteger&lt;br /&gt;{&lt;br /&gt;   get&lt;br /&gt;   {&lt;br /&gt;      CanRead(&quot;SomeInteger&quot;);&lt;br /&gt;      return _SomeInteger;&lt;br /&gt;   }&lt;br /&gt;   set&lt;br /&gt;   {&lt;br /&gt;      CanWrite(&quot;SomeInteger&quot;);&lt;br /&gt;      _SomeInteger = value;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now this seems great and all, but how many times in a real world enviroment are you going to be able to determine whether or not something is Read/Write for a user simply by calling a property? In my experiences, the Read / Write capability for a property depends on the object&#39;s actual state. For example, upon submission of an order, the customer should be able to add items, set the address, and possibly (but not required) make payment. Once the submission takes place, the Items collection should potentially be read only for the customer. Which, I agree, you could do using some cool logic in the CanWrite method, but now your CanWrite method must know the state of your object and be a &quot;Smart&quot; method. What if items can only be added if the address hasn&#39;t been set yet, and or if the customer has placed more than 10k orders they can edit requests on the fly? Now your CanWrite() method needs to talk to other objects in your object graph and/or other objects independant of your instance, maybe a static method that says, IsItemInStock()? The only good use I can see for CanRead / CanWrite is for security purposes. If only certain people can Read / Write properties this works great. Otherwise I don&#39;t really understand the use of it. Also, I really don&#39;t like that you pass a STRING into the method. I&#39;ll talk about the actual code generation in a second, but its not like CSLA couldn&#39;t generate or make a MyClassPropertiesEnum and pass in the enumeration for a much stricter logic evaluator.&lt;br /&gt;&lt;br /&gt;So now, onto the code. Mind you, CSLA does come with some CodeSmith templates which auto-generate your code for you (at least the most basic code anyways), however, here is what my fellow team mate has found with the code generators. As with almost all code generators there are some drawbacks. A major drawback in my opinion is the code generation is commentless. I am a humungous fan of comments. Even on my properties that seem simple like public int MyClassRecordId; Obviously, this is my primary key in relation to the object, but I still put comments that state such. As with 99% of code generators, comments are forgotten. He did find a possible work around, but it would involve creating your own CodeSmith template. Also, a standard class with about 20-30 properties generates over 900 lines of code for the business object. 900 lines of code. Yes, 90% of this is so that CSLA can create its mobile object and its save, fetch, delete logic, but still. &lt;br /&gt;&lt;br /&gt;Now, don&#39;t get me wrong, I know this post has been quite negatory, but I think CSLA would work great in some instances. Winforms obviously, especially for enterprise wide apps where at certain times, some methods perform HUGE amounts of intense calculations and logic. However, WebForms already run on a super server, and most likely are already farmed out. So using CSLA doesn&#39;t really buy me anything except for a standard way of doing things.&lt;br /&gt;&lt;br /&gt;I also am of the opinion of coming up with a global set of standards and a framework to use for an enterprise. I have now worked in the same .NET environment for over a year, and I can now see how a diverse team can run into issues when everyone is doing it their own way. I can also see the advantages. For example, my team at work uses NHibernate and ActiveRecord. We have adopted these frameworks for our data access which pretty much always ties directly into our object model. In our instances of the not so huge apps, this works great. We also write WebForms pretty exclusively, so AR / NH work perfect for us. However, we have come to a bump in the road. Even though our team is quite small (only 3 full time .NETters), all of us write our objects differently enough that there would be about a day&#39;s spin up for us to transition between projects. Not too huge, but we are on the same team, so one would think we would do it all the same. This will lead me to my next few posts which will talk about some things an enterprise (or team wide) framework should include and how my team plans on implementing the framework we create. I am definitely up for ANY feedback including downsides to our decision, better options that are out there, if we are heading down the right track, any feed back is great. We are not out to create the worlds best framework, we are just out to try and find an easier, more productive way to do something. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/csla-analysis-my-lead-up-to-our-own.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5306712688887994524.post-2056915095975363608</guid><pubDate>Wed, 02 Jan 2008 00:20:00 +0000</pubDate><atom:updated>2008-01-01T19:36:39.872-05:00</atom:updated><title>Visual Studio 2008 Class Designer</title><description>First off I want to let everyone know that baby Noah and mommy are doing great. Daddy is getting less sleep than ever, even in college. So that&#39;s good. Now to the good stuff. Yesterday I was playing around with the Visual Studio 2008 class design which I usually never use because I have all sorts of snippets that are just as easy for me to use than some designer. Well a small pet-peeve I have with the VS2008 designer is its implementation of Properties. Now, I may just be a moron since I never use the class designer, but one would think that with the new property syntax in .NET 3.5 the class designer would generate completely executable properties like this:&lt;br /&gt;&lt;br /&gt;public int SomeInteger { get; set; };&lt;br /&gt;public string SomeString { get; set; };&lt;br /&gt;&lt;br /&gt;This syntax is awesome. It saves me from having to implement my own custom GETTER and SETTER, assuming I don&#39;t have any logic around them like authentication or what not. But of course, MS F*&#39;s us by putting some stupid ass syntax like this for properties in the class designer:&lt;br /&gt;&lt;br /&gt;public int SomeInteger&lt;br /&gt;{&lt;br /&gt;   get&lt;br /&gt;   {&lt;br /&gt;        throw SomeDumbException(); //I think its NotImplementedException();&lt;br /&gt;   }&lt;br /&gt;   set&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;So how freaking worthless is this? Now I have to go and rewrite the damn logic that the designer generated. So what did it save me? Why would I even use the designer when I have to go and rewrite the code anyways. I should just use something like VISIO which also generates code from its diagrams. Another thing I don&#39;t like about the designer is how it implements relationships. Now, before I continue ranting about the class designer, I want you to know that I never used the class designer in VS2k5 so I may just be a novice, however, I&#39;m still pissed off. Anyways, back to relationships. Now I would think that you create the property in your object, and the designer would recognize its type and automatically add a relationship for you. But this isn&#39;t how it works. You have to add the relationship BEFORE adding the property, then assign its parent / child. However, its not really Parent / Child at all. Its more object to object since to my knowledge I could not figure out a way to create a parent to multiple children relationship on the parent side. I couldn&#39;t say IList&lt;child&gt; Children in the parent. I&#39;m guessing because the MS way to code this is to create some ChildManager to manage all the children, but again, the manager would still have a list of children somewhere so there is not relationship of the parent to its children. One thing I did like about the class designer though was its ability to include XML comments. I am a super fan of XML comments AND regions. If anyone has seen my code its all about Regions. I region each property, I region all the properties, and I region the entire class. I do the same for fields and methods. SO everything is shrunk down so I can read it all on one screen. Why MS didn&#39;t incorporate this XML commenting ability into the DLINQ designer is beyond me. It is totally beyond me. That is one thing I really don&#39;t like about the DLINQ designer is its inability to add comments to the generated code which makes it damn near impossible to simply HAND OFF to another developer. Anyways, that&#39;s enough ranting for now. I am going to try and take a look at the DLINQ designer in a later post this week if I have some time. Going to try and rewrite an old ASP website I have been meaning to take care of for the past 2 years. To the end, I shall go, but to the beginning is where I end up.</description><link>http://flipstechnologyposts.blogspot.com/2008/01/visual-studio-2008-class-designer.html</link><author>noreply@blogger.com (Flip44)</author><thr:total>0</thr:total></item></channel></rss>