in

Fort Worth .NET Users Group

Dot Net Tricks

  • ASP.NET Sucks and It DOES Matter

    This is partially in response to this somewhat infamous article by Jeff Atwood:

    http://www.codinghorror.com/blog/archives/001119.html

    In this Jeff mentions that although PHP as a language and platform sucks, it doesn’t matter.  Its low barrier to entry has allowed PHP to become the defacto standard for major and minor websites all over the internet, as well as many decent software packages, such as shopping carts and Content Management Systems.  The fact is there is a lot of great software written in PHP, despite the language’s overall suckiness. 

    With ASP.NET, my web framework of choice, things are a little different.  Sadly, I must confess that ASP.NET also sucks, although in a different way, and in my opinion it does matter.  This limits the number of decent free and even commercial software packages.  Trying to find a decent, user friendly, engaging software package such as a shopping cart or CMS in ASP.NET is difficult at best, especially if you want one for free.  ASP.NET may hold a place of distinction among enterprise applications and large corporate websites, but in the world of social networking sites, shopping carts and the like it’s virtually a no show.  On the enterprise ASP.NET has done rather well, competing with the other heavyweight: Java.  But for basic websites, it well….sucks.  At the web shop I work at now, I had almost come to the conclusion that asp.net is the wrong choice of technology for us or at least for the majority of our small business customers.   Our sites are too small, the work and overhead of ASP.NET make development too slow for these simple projects and the lack of good software packages such as shopping carts and Content Management Systems put us behind our competition.

    Take for example, our CMS.  We’re using arguably one of the best commercial CMS applications on the market for asp.net and still the software is complicated to install, upgrade, extend, style and manage.  Our clients have issues as well.  Drag and drop is supposed to work, but it doesn’t in certain circumstances.  The WYSIWYG editor adds extra span tags or shifts formatting and spacing around seemingly at a whim.  The user experience could be a lot better and faster.  I can feel the weight of viewstate with every click in that CMS.  In the shopping cart arena, things are nearly as bad.

    So why is it that PHP sucks and yet there are tons of websites and really good software packages for it, many of them for free?  With ASP.NET, it’s difficult to find good applications, especially among the open source community.

    First, there is the overall learning curve of ASP.NET.  I’ve already documented a lot of the ways in which ASP.NET sucks so I won’t go into too much of that here.   Search google for “ASP.NET sucks” and you’ll get a lot of really valid points from people that apparently are a lot smarter or less stubborn than I am, because they gave up on it back in version 1.1.  Suffice it to say, ASP.NET development is complicated and much harder than it needs to be.  But it goes beyond that.  Its also a very difficult paradigm to understand for anyone familiar with other web technologies: html, css, flash, javascript, php, java/jsp, coldfusion or even classic asp. ASP.NET looks, feels and acts different than almost any other server-side web technology, and integrates poorly with the client technologies.   ASP.NET is almost entirely ignored by web designers.  The barrier to entry for the average web developer or designer means that it has not become the standard it could be, at least for the average website market.   I can some up this barrier to entry in two words: “Web Forms”. 

    The Web Forms paradigm that ASP.NET is based on is both a blessing and a curse.  On the enterprise where ASP.NET does well, web forms is a blessing, at least historically.  This is because it mimics a forms-based, stateful, event-driven technology such as win forms or even java desktop applications.  The web forms abstraction makes web development seem similar to desktop development.  Where this created hurdles for existing web designers and developers trying to learn ASP.NET, it lowered the barrier of entry for existing desktop programmers doing Visual Basic, Java, Visual C++ and heck, even Microsoft Access.  In addition, the object-orientation of the .NET Framework and Microsoft’s two revered languages, C# and Visual Basic.NET, was attractive to programmers coming from a Java, C++ or Visual Basic 6 background.  .NET has a simpler class library and structure than COM or VB did, and is familiar to the point of Déjà vu for java developers.

    But for your average web designer, who may be an Html, CSS and Javascript guru, ASP.NET is an anathema.  Take for example the ASP.NET control hierarchy.  Using server controls in ASP.NET means that Html is generated in a way that interface designers can’t control very well.  Sure they can slap a “CssClass” attribute on most controls but the actual Html generated is hidden from them and can throw a lot surprises their way.  Worst still, this generated code messes with the Html tag hierarchy that a lot of designers rely on in their CSS and Javascript.  Usually designers will get used to the built in server controls and figure out their idiosyncrasies, but as soon as you throw in a 3rd party control, it’s a whole new ball game with a new set of rules, quirks and surprises.  We’ve gone thru a lot of this trying to skin third party controls and both myself and our interface guys have pulled our hair out trying to get the CSS “just right” in order to properly style a control that spits out mountains of Html and javascript and CSS of its own that we can’t see until runtime and which has a lot of dependencies on certain CSS classes, Ids and tags.  Its just TOO HARD.

    But the cardinal sin of ASP.NET is how it deals with the all-important Html ID attribute.  I can’t say this strong enough, so forgive my crudeness, but ASP.NET RAPES the ID attribute.  At my second ASP.NET job, my manager was constantly asking us to do challenging and interesting user interface tweaks using JavaScript, and every time he did I just groaned inwardly in a way that I never had to with Coldfusion or classic ASP.  ASP.NET in its effort to emulate that stateful, event driven, desktop paradigm, goes and wreaks havoc with the all the server controls’ ID attributes.  ASP.NET dynamically changes the ID attributes of any Html that is generated by a server control.  So you have to ask for the generated ID through server-side code.  The ID can’t just be hardcoded because it may change at runtime depending on the hierarchy.   So what was once a simple integration between Javascript and server-generated Html now requires the developer to expose the control’s ClientID to javascript thru nonsense like this:

    <%# this.textBox1.ClientID %>

    Which also requires a call to Databind() somewhere because using Response.Write or <%= %> causes the infamous “control collection could not be modified because the control contains code blocks” exception. 

    In addition, web designers also rely very, very heavily on the ID attribute and tag hierarchy for coding CSS.  So when the tag hierarchy and IDs either are not known or they change for the same reason, this breaks the designers CSS and causes them a lot of headaches to get them working.  Unfortunately, ASP.NET does both, so it makes styling a page like trying to hit a moving target. 

    In other words, it now requires a programmer who remembers all these ASP.NET quirks to get the user interface working, and looking, right.

    Finally, ASP.NET’s web form model adds a huge learning curve from those coming from other server-side technologies.  PHP, Classic ASP, Ruby-on-Rails, Coldfusion, JSP  (perhaps excluding Java-server faces, which I know almost nothing about) all have similar ways of doing something.  You markup an Html page and embed server side code in it, usually using some kind of separate tag syntax.  Web Forms don’t really work this way and Microsoft doesn’t really encourage it.  What they were trying to do was noble—they were trying to separate markup (html) from presentation logic (C#, Java, VB, etc.)  Whereas the other technologies mix them together, Microsoft was rightly trying to separate them out.  And I have to admit that a well designed aspx page and its code-behind is a beautiful thing to behold.  The aspx contains only Html and Server-Control tags, and the code-behind contains only C#. 

    But consider this, let’s say I have a  grid on the page full of tabular data containing customers and their current balance.   I want the Customers being displayed on this grid that have a balance greater than zero to have their balance highlighted in red.  What is involved in accomplishing this relatively simple presentation task?  Just breeze thru the following steps…

    1. Wire up the GridView’s ItemRowBound event to an event handling method.
    2. In the event handling method, check that the current row’s data item isn’t null (this avoid exceptions because the headers and footers don’t have data associated with them.)
    3. Create a local variable for the Customer data, like a Customer object, dataset, etc. 
    4. Now cast the row’s data item to whatever you’re binding to—the Customer object, DataRow, etc.
    5. Oh, wait if you’re binding to a dataset, you have to cast the row’s data item to a DataRowView, not a DataRow.  After 6 years of ASP.NET, I still don’t know why that’s necessary. 
    6. Now that you have your data, check the customer’s balance to see if its greater than zero.
    7. Now use FindControl on the current row of the GridView to find the control  (label, textbox, etc.) that contains the balance, or use the row’s Cells properties if there’s not a control nested in there.  If you have a control, you also have to cast it to a control.

    Now, I’m not being completely fair, because part of the work above is not the fault of ASP.NET, it’s the fault of a strongly typed language with all its casting necessity.  But much of the casting would be unnecessary even in JSPs which use another strongly typed language. 

    When I first was learning asp.net and tried to do the above tasks, I was lost.  My instinct was to start a “for loop” and put in one “if” statement and be done with it, but that was not really feasible with a DataGrid, and probably wouldn’t be recommended by Microsoft or the ASP.NET community.  I had a long learning curve ahead of me.  Now after 6 years of ASP.NET development under my belt, it’s a piece of cake and I do enjoy the separation of concerns.  But I suspect a lot of web programmers coming from other server-side platforms, took a look at all this crazy web forms stuff and swore it off.  Its different, its complicated and it slows down development. 

    Which goes back to what spawned this post.  Why is it so many public facing websites are written in PHP, and there are so many great shopping carts, CMS’s and other free software for it?    Why are there so few for ASP.NET?  Its because ASP.NET was designed for desktop programmers and almost completely ignored existing web designers and web developers. For all its flaws, for all its lack of object orientation, its global functions, its quirkiness and ugly syntax, PHP is friendlier to web designers and web developers.  It’s friendlier with CSS, Javascript and by extension, all the cool UI toolkits out there like Dojo, Scriptaculous and Prototype.  This doesn’t make it better, and I’d certainly choose ASP.NET in a heartbeat for a complex, line of business, web application over PHP.  But if you need a small to medium size website up quickly and cheaply, nothing beats PHP and its slew of free, open source, scripts and applications.

    I believe there is hope for ASP.NET however.   Ironically, this comes not from some quick and dirty code-generating, drag and drop toolkit that Microsoft is throwing over the wall, but for something that was designed to fix some of the alleged flaws in the web forms model for enterprise development.  Enter the ASP.NET MVC framework. 

    According the ASP.NET website, the MVC framework and the design pattern its based upon has the following benefits:

    • It enables you to achieve and maintain a clear separation of concerns
    • It facilitates test driven development (TDD)
    • It provides more control over the URLs you publish in the application and over the HTML that is emitted by the application

    The first two bullets will probably not make a blip on the radar of most web designers.  But the last part, about full control of the Html, as well as other deviations from web forms, could actually lower the barrier of entry to ASP.NET development.  MVC styled development isn’t going to muck with my html tags, it’s not going to change the ID attributes, there’s no viewstate, there’s far less reliance on events and controls.  Forms can post anywhere.   You can throw an “if” statement or a “for loop” in the middle of the page to generate Html without it being quite a sacrilege.

    So besides solving a lot of the “enterprisey” problems such as better separation of concerns and TDD, it may actually make web development friendlier to web designers and non-ASP.NET web programmers.  Maybe there won’t be an immediate slew of well designed MVC shopping carts and CMS applications, but there might be a renewed interest in the ASP.NET platform from designers.  So in a sense, ASP.NET developers can now get the best of both worlds: Enterprise friendly architecture, and web designer friendly simplicity.  I can get my nice C# objects and the elegance of the .NET framework class library, without dealing with web forms complexity.  There might be hope for ASP.NET yet.

     

     

     

  • sql server management studio has “backup sets” and “destinations on disk” disabled

    I ran into this little gotcha a little while ago, so I thought I’d share it and break my blog silence.

    One of our clients hosts their own sql server (express) and website, and I kept noticing that there was no way to do a backup.  When I went into sql management studio and tried to add a backup destination, it didn’t give an option for file name, only tape.  And the “Backup device” section was disabled. 

    Even running the “backup” command from t-sql didn’t work.   It gave me an access error.  This was my clue.  The problem was that the sql express service was running as the “Network Service” login, which didn’t have access to any folders on the file system.  I gave it access to one folder, and then Management Studio let me pick destinations from the file system.  I was also able to add backups sets and run backups from the command line.  I could have changed the network service to run as “system” but didn’t to mess with someone else’s box. 

    Pretty simple fix, but not very obvious what the problem was.
  • FWDNUG Meeting Notes and Slides

    Thanks to Stephen and the other members at the Fort Worth .NET User Group for having me speak.  I enjoyed it and hopefully my audience did too.

    I'm sorry this has taken a while to post, but as promised I have all the slides and a list of resources like Fowler's POEA book in a big zip file.  Also there is a VS 2008 solution with a code snippet using ADO.NET Entity Framework Beta 3.  You can download the whole thing here:

    http://www.dotnettricks.com/downloads/orm_presentation.zip

    Finally, Kevin here at Enilon was kind enough to record the whole session for posterity.  So if you missed it, you can listen to it on your mp3 player:

    http://www.dotnettricks.com/downloads/FWDNUG-03-08-MP3.zip

    Thanks,

    Craig

  • I'm speaking at the Fort Worth .NET user group

    On March 18th I'll be speaking at the Fort Worth .NET user group at Justin Brands.  The topic will be a favorite of mine: O/R Mapping Patterns and Tools. 

    Come by say hello or throw tomatoes.  Info is below:

    http://fwdnug.com/blogs/meetings/archive/2008/03/11/march-2008-meeting.aspx


  • Warn3d By CrueLSaw

    Today I got a very interesting request from my boss.  There was one of our sites that had suddenly been defaced with the following text:

    "Warn3d By CrueLSaw"

    After some research by one of our Senior Developers (Thanks Pete) he found that this CrueLSaw guy was very busy hacking into and defacing classic asp and even a few PHP websites. 

    It was our old friend sql injection--the guy had found the admin part of our site, and plopped in some sql into the password text box like this:

    ' OR 0=0 --

    Of course the long gone developer of this code didn't parameterize their sql or use a stored procedure.  This effectively let him into our site to deface it.  We're lucky that CrueLSaw only warns people and didn't truncate our tables. 

    To be fair, this site was a Classic ASP website done around 6 years ago and the developer back then probably didn't know a thing about sql injection, because few people did at the time. But some lessons are painfully learned.  The solution was simple--just use a stored proc or a ADO provider that allows paratmeterized SQL.

    If you're company's website is having this problem, then fire me an email here and I can fix it for a small fee:

    http://www.craigbowes.com/Contact.aspx

    Thanks for the warning CrueLSaw.

  • Should your production build be different than your development build?

    Kyle Bailey invited some criticism in his article, so I'm going to deliver it.  You can read the original article HERE, but to sum up:

    "The basic idea Donald described was thus: Just because you build your application one way in Visual Studio during development, doesn't mean you need to build your releases the same way. Especially if you are using NAnt to create your releases because then you can do it however you like."

    I use nant too.  But I can tell you, I do NOT make my nant build different between production, staging and development the way they're suggesting.  I point my nant build to my solution file and have everything run off that, using the <MSBUILD> task.

    The reason I don't do this is because i've been burned by something similar to this in the past.  When i first started using vs.net 2005 and projectless websites, i started looking at the different build options and also at web deployment projects which are just friendly MSBuild wrappers.   Although I don't like projectless websites (a topic for another post perhaps) everything went more or less fine with my new VS.NET 2005 project, until I went to deploy.  Then MSBuild crapped a log.  The site wouldn't compile.

    After figuring out how to get msbuild and vs.net to show me more explicit error messages other than "aspnet compiler failed' or some such ***, i found out the problem was due to 2 classes with the same name.  Under normal development circumstances using projectless websites, 2 classes (or pages) can have the same name without any problems.  This is because each page gets compiled as its own assembly.  However, when I was deploying, i wanted everything in one assembly.  This caused MS Build to fail, because 2 classes with the same name in the same assembly isn't allowed.

    So i learned early on not to create any surprises for myself when it came to staging and production deployments.  Make everything as similar as possible, so you catch issues early on.

    That being said, much of my problems with that had to do with projectless websites and third party code that had the duplicate classes.  I use web application projects now and I'm a lot happier.  I also use nant instead of web deployment projects, and nant is probably a lot more flexible.  But I'm still hesitant to differentiate my development and other builds because I don't want any surprises.

    There's perhaps one other reason not to do what Kyle and his friend Donald are suggesting--its more work.  Remember the D.R.Y. principle?  Duplicating anything in IT is bad.    Under Kyle's methodology, It sounds like if i add a class to my vs.net solution, i then have to add it to my nant build file.  Same for including or excluding references.  This just sounds like additional maintenance pain caused by duplication. 

    Sorry Hillbilly, you lost me on this one. 

  • Lessons Learned From the WAM Charity Event

    I just got back from the WAM charity event that i mentioned in an earlier post.  I want to again thank everyone on my team for all their hard work.  It was also amazing to see what the other teams had built in such a short timeframe, sometimes with only one or two developers.  I learned a lot about development and project management this weekend, so I thought I would share my thoughts.

    This weekend was a whirlwind of coding, coordination, sweat and tears.  Our team consisted of 5 developers working on a small project which had around 8 tables (not including the aspnet membership tables) and 20+ pages.  The project was not your run of the mill standard website that could be built using a CMS.  Although small, there were significant complexities: each user role had to see specific things, there were complex relationships to consider between different objects and their underlying tables, there were overlaps between different sections of the application that needed some code reuse in the form of controls, and so on.

    But more complex was the team dynamic.  Tina and I had worked together, Matt, Nolan, Tuan and I had not.  Also, we were constantly reminded of the "Mythical Man Month."  We kept joking that since we had 5 developers on such a small project, we should go a lot slower.  This was not far from the truth.  It took considerable effort not to step on each others toes.  Below are some of the things that I took away from the experience.

    Designate a Clear Leader

    Although I had the initial idea to form our group and had invited Tina and Matt to come to the event, there was no rule saying that I was the project manager or lead developer.  Also, I think I was hesitant to take on this role for several reasons.  First, I had created a visual studio solution ahead of time with the telerik controls and wilson orm already setup, because Tina and Matt and I had already decided upon this.  However, I didn't necessarily want to dictate more technology decisions to Tuan and Nolan than what we already had.  Also, both Nolan and Matt had just as many years of experience (or more) on their belt that I had.  This lack of a clear leader in the group made it difficult to make decisions at times, especially the first day when we were designing the application by drawing screens.  We had to come to consensus or vote on a lot of decisions which caused us to move slower.  Often, people did not want to take sides when there was a disagreement, so it was hard to even get a vote.  I think that either we should have voted on a leader from the very beginning, or WAM should have assigned a group leader to each project.  This doesn't mean that there can't be discussion or that you need a dictator in charge, but i think having a clear leader would have avoided a lot of the group's "Analysis Paralysis."

    If Time's an Issue, Use Familiar Tools

    Every developer has their own way of doing things.  One of the problems of software development is that the same problem can be solved different ways.  I think this force definitely gave us some hurdles to jump during the event.  For example, as I mentioned Tina, Matt and I were all familiar with O/R Mappers and the Wilson ORM we had decided to use.  Nolan and Tuan were not.  This wasn't TOO bad because we had three people that could help the other two.  

    Early on, we had decided we all wanted to write the code in a somewhat consistent way.  Matt had suggested that we use GridView and FormView on the same page to create our screens.  So when the user clicked on a record in the gridview, the page would postback, the formview would databind and and gridview would be hidden.  Matt had used this technique successfully on a lot of applications.  So we all copied Matt's initial screens so we could tailor them to each of or pieces of the application.  I think we were all eager to learn something new.  In retrospect I think this was a mistake.  Matt was the only one familiar with this way of writing the UI.  So he ended up having to stay very late when Tuan and Nolan's screens had problems because he was the only one who understood the process.  I had a lot of issues myself but finally gave up on FormView and just used a panel to show and hide the form.  Matt may still disagree with me but i think formview and detailview do not add a lot of value unless you can take advantage of two way databinding or autogenerating the fields on the form.  Unfortunately, this is hard to do with the Wilson business objects and the ActiveRecord pattern we were using.  My experience has been that FormView, DetailView and Datasource controls really require you to do things the microsoft way using datasets or a very specific structure to your business objects, in order use them effectively.  I noticed a lot of us had duplication in our code and struggled with the myriad of events raised from the GridView and DetailsView on the same page.  Towards the end, I think most of us reverted to using the method that was most familiar to use, which probably made the codebase less consistent.

    In addition, I was the only one who understood subversion.   I think this was a problem as well.  I became a bottleneck whenever a conflict arose, which was often due to the small number of screens in the application.  The project file was especially problematic as all of us were constantly adding new files.  In retrospect, I think we should have used the "Lock..." feature in subversion and tortoise so that we could simulate VSS's exclusive checkouts.  Unfortunately, I didn't think of this until the tail end of the event.  There was lot of stepping on each other and versioning conflicts because of the number of developers in such a "small space".   I think the lesson learned here was that "exclusive checkout" is actually more productive than "multiple checkout" when you're on a small project with that many developers in that short of a time span.

    Three of us were using TortoiseSVN but Tuan and Matt were using RapidSVN.  I had suggested before the event that we could use any client with Subversion, but I had very minimal experience using RapidSVN.  So it might have been easier had we all been on the same Subversion client as well.  

    Finally, even the Telerik controls were an issue.  We used the RadEditor to allow the users to enter Html content.  I got the RadEditor working but then I wanted to use the same image browser/uploader in the editor in a photo album part of the site.  I was able to get some javascript working to launch the image browser without showing the RadEditor, but then getting the name of the file back to the page took a long time to figure out.  Matt, Nolan and I spent hours on this alone.  

    When You're Going the Wrong Way, Turn Around


    Several times during the event, I noticed that one or more of us would get stuck on something.  Because of the short time frame, we were often afraid to give up and start over with another tool or technique.  The fear is that if you have already spent 2-4 hours on something, you don't want to give up when you feel so close to finding the answer.  The running joke became: "I just need 5 more minutes!"  Of course, five minutes often turns into hours.  I think we all might have gotten more sleep if we had been willing to give up on continuing down a certain path and try something different instead.  Sometimes, you have to know when to cut your losses.

    Don't Have Too Many Cooks in the Kitchen

    It took us a while to learn this, but by the end of the event, Tina and Tuan were just styling pages while the other three of us wrote code.  There just wasn't enough "space" in the application for us to avoid stepping on each other's toes.  I have already made reference to the "Mythical Man Month" but let me reiterate--having 5 developers does NOT mean that the team gets 5 times as much work done.  There's a lot of overhead because with more developers you need more coordination, communication and management.  Often, one person has to wait on another.  Truly you cannot make one baby in one month by getting 9 pregnant women together.

    Good Programming Takes Time


    Of course we all know this.  But one aspect to having such a short time frame to build an application is that the problems you run into every day become incredibly more visible and real when your project must be completed in hours instead of weeks.  I am amazed at how our team came together and at all the projects that the various teams finished for their charities.  That being said, i have no doubt that our code would be more maintainable and our application more stable given more time and more sleep.  About halfway thru the first day of the event and I realized I had signed up for and dragged in poor Tina and Matt into my worst nightmare: the ultimate unreasonable deadline.  I'm sure our charities will need further help as bugs are fixed and holes are plugged in the weeks and months ahead.

    Finally, I Need Practice Speaking in Public

    The team cruely nominated me to demo the application before all the teams, charities and attendees while being filmed.   Nervousness and exhaustion had obviously taken their toll on me as a rambled on for about 30 seconds before I got focused enough to talk thru the application.  I tried to be brief but i think the end affect was that I talked a little like the micro machine guy so I could get off the microphone.  I'm due to speak at the Fort Worth Dot Net User Group soon so hopefully i'll be more relaxed and clear for that event.

    Wrap Up


    I'm not sure whether I would volunteer at an event like this again.  The stress of the short timeframe and the lack of sleep made me chant "NEVER AGAIN!!!" like a mantra shortly after it was all over.  But looking back I learned so much and it was for such great charities that I might consider taking another stab at it next year.  Or at least, maybe helping out in my spare time.


















  • A little reflection

    This is just a quick post. 

    The other day, I needed to take all fields from a business object called QuoteLead which represents a Sales Lead for an insurance quote, and send it to to another system in a name/value format to post via HTTP.  This is because we're integrating with a 3rd party service that requires an HTTP post, rather than a web service (SOAP would cost extra, and the client didn't want to pay the montly fee.)

    So I ended up having to do a bit of refleciton, in order to send all of the business object's properties in a format like this: firstname=Bob&lastname=Smith&address1=123 some street&city=fort worth

    etc. etc.

    So I ended up doing this:

            public virtual string SerializeForHttp()
            {
                QuoteLead lead = this;

                PropertyInfo[] props = lead.GetType().GetProperties();
                StringBuilder builder = new StringBuilder(props.Length);
                foreach (PropertyInfo info in props)
                {


                    string name = info.Name;

                    object value = info.GetValue(lead, null);
                    if (value != null)
                    {
                        builder.Append(name + "=" + value.ToString() + "&");
                    }
                }

                return builder.ToString();
            }

    I ran into a couple of gotchas:

    • First, I tried passing various binding flags to the GetProperties() method, but i kept getting weird errors.  Using the parameterless version of the method got me all the public, instance methods including inherited ones, which is exactly what i needed.
    • You'll noticed I check the return value from GetValue() for null.  This is because if i call the ToString() method I'll get an error for values that aren't there.
    • Finally, the QuoteLead object i was "serializing" in this fashion has a related "State" property,  an object which represents one of the United States.   This was an object, not just a string in QuoteLead. I had to overload the ToString() method in State so that it would return the State abbreviation from the database:

      public override ToString() {
      return this.StateAbbreviation; }

    If anyone is interested, my object model is auto-generated using Custom Codesmith templates that integrate with NHibernate.  We've implemented the ActiveRecord pattern (because Castle ActiveRecord had their site going down all the time, and i like the database to gen the business objects on small projects like this.)  We nicknamed this framework "SNARF" for Simple NHibernate ActiveRecord Framework.  In some future posts, I'll share the framework and templates.


  • Missing Query String Parameters and What To Do About Them

    When you're writing code in an asp.net page (or any other type of page) you often come across situations where you need to know what to do should the user tamper with the query string parameters.

    I won't go into security issues here like sql injection attack or how you shouldn't pass credit card numbers on the query string--I'm assuming that you have that covered.  I'm talking about a much more contraversial subject: what to do if a query string parameter IS JUST PLAIN MISSING.  For example, say you are expecting a url like the following:

    http://localhost/ViewArticle.aspx?articleID=347


    but you only get this:

    http://localhost/ViewArticle.aspx


    Some developers advocate showing a friendly message.  Others think you should redirect back to a listing page, which in this case, would be something like /ListAllArticles.aspx.  Some suggest swallowing any exception that might arise.

    I say go ahead and THROW THE ERROR.  I know that sounds counter-intuitive, but hear me out.  If you have a high traffic site, Inevitably you will get some small minority of users, probably geeks like us that will tamper with the address bar and attempt to put in weird things in the query string.  And you should definitely check to make sure they aren't putting in anything that would corrupt data or compromise security.  But chances are, most users are just going to click the links and leave it at that.  So if you're missing a parameter, its probably because YOU the developer did something wrong, and YOU need to know about it.

    What I do instead is setup site-wide error handling, usually with ELMAH (which Andrew wrote about here.)  Then if i get an error, i get emailed.  This way, I know if one of my pages is linked incorrectly, and is missing that query string parameter.   Then i can fix it.  If i just ignore missing parameters, I won't realize my users aren't seeing the right content.

    Case in point, I kept getting errors on a production website because the page that was used to display an image gallery was missing the "GalleryID" parameter.  I kept getting error, after error nagging me.  I finally looked into it, and it was because i had configured IIS to redirect and older domain to the site's new domain.  The problem was Google and other search engines had already indexed using the old domain and they were pointing to particular image galleries with URLs like this:

    http://www.OldDomain.com/View-Gallery.aspx?galleryID=234

    However, when i got the email, it showed the query string parameters WERE COMPLETELY GONE.  I looked at the referrer and saw that they were coming from google, yahoo, etc.  With a little help from Fiddler (an HTTP listener) i found out that the way i was redirecting the traffic in IIS was actually removing the query string parameters entirely, so the users were getting redirected to a url like this:

    http://www.newdomain.com/View-Gallery.aspx

    No parameters.  There's an easy fix in IIS.  Check out Permanent Redirects with Query String

    (Incidentally a "Permanent 301 Redirect" lets google rank you higher than if simply point all domains to the same website.)

    If my site had not been logging error messages when the query string parameters were missing, I would never have known my users were being redirected to the wrong place.  

    So don't hide errors due to missing query string parameters.  This is almost like swallowing exceptions in my book.  Your page is like an object or method (in asp.net pages ARE objects!) so if its missing required parameters, it should throw an error.
Copyright FWDNUG 2008
Powered by Community Server (Commercial Edition), by Telligent Systems