CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

October 2005 - Posts

  • Burning the VS 2005 DVD ".img" file

    If you've downloaded the VS 2005 .img file and use software like Nero, you'll quickly find that it doesn't support the .img file. 

    Simply re-name the .img file to .iso, and Nero will burn the DVD

    Just thought I'd post this tidbit, in case anyone else runs into this problem.

    Now, whether or not I'll have better luck than Geoff installing the thing remains to be seen. 

    -Brendan

  • Validating Business Rules and Returning Errors

    Today, I ran into a situation where I needed to validate some Business Rules (BRs) within a business object.  To do this, I needed to call into some secondary business layers to do some checking, and if a business rule failed, I needed to note “Why” and return this result back to the caller. This final caller in this case was client connecting to a Web-Service endpoint.  My problem arose because I needed to know two things, IF and WHY the BR failed.

    At first glance, I thought I could just throw an exception, and catch it within my business tier, the exception itself would tell me the IF, and the exception's message the WHY.  I could then repackage a result object which would be returned to the web client caller.  I asked the CodeBetter guys what they thought, and was instantly reminded that Rule #1 is not to use exceptions to control program flow.  

    Raymond Said :  You violate the primary rule of exceptions: do not use exceptions to control the flow of the program.  If you're expecting and exception to occur in that logic, I would let it propagate back up the call stack.  Just my opinion.  Some people do exactly what you are proposing and have no issues about it.  I personally don't like to see them used in that manner.

    In fact, I knew this, but forgot that I had blogged about it over a year ago (and I thought blogs were supposed to help you remember ).  The big thing I learned is summed up by these two “almost rules” by Rico Mariani: Exception Cost: When to throw and when not to. (This is actually mentioned in the comments of Jeffrey’s recent post, Why are error return codes evil? - level 100.)

    Almost Rule #1

    When deciding if you should throw an exception, pretend that the throw statement makes the computer beep 3 times, and sleep for 2 seconds. If you still want to throw under those circumstances, go for it.

    Seriously, people throw much too often, and for things that aren't really very exceptional at all. In fact, my own opinion is that the framework itself throws far more often than it should. The actual throwing of exceptions is sufficiently costly that I try to limit it to cases where I'm certain that less than 1 call in 1000 (99.9%) to a particular service will require an exception. This means throwing exceptions on things like invalid arguments to an API is probably just fine, but on the other hand throwing an exception due to invalid user input, or badly formatted text from an external system, could be a bad idea. Significant use of exceptions in business logic validation is more often a bad idea than a good one, so be careful out there.

    Almost Rule #2

    If you think it will be at all normal for anyone to want to catch your exception, then probably it shouldn't be an exception at all.

    Again, my favorite consumer of exceptions is a generic exception handler at a fairly high level on the stack. Anything that fundamentally needs to be dealt with at a lower level should be looked at suspiciously. Often such a beast would fail the “only 1/1000” of the time test. Since doing control flow with exceptions is alot more expensive/confusing than other forms of control flow its best avoided if the special handling is commonplace.

    What I like to see is general purpose logic for state cleanup, transaction abort, reset and retry. What I don't like to see is “downgrading” an exception into a return code, or routinely being able to “ignore” the exception and proceed. Those latter cases are usually a bad sign.

    After reading this I realized that my original solution was a bad, bad idea.  So, what to do?  Remember I needed to know both the if and the why.   Returning two things is somewhat of a problem, since you can only return one thing from a method.  Jeffrey suggested the following:

    Another option is to have the validate method return a collection of strings of errors.  If the collection is empty, there are no errors.

    So, basically an empty versus filled collection would signify the IF and the collection text the WHY.  I asked him if he thought that this was somewhat of a code smell, since the IF is inferred, and Jeffrey replied with the following:

    It would be a code smell in a high-level API, but if this was wrapped inside the method that returns your result object, then it wouldn't be exposed to the outside.  It's really up to you, but in that case, I'd name the method (GetErrors) or something like that.  Then it might be a more clear that no errors back means you can continue.

    Okay, fair enough.  But it still not a perfect solution to this problem, IMO. I thought I’d post about this because its the kind of real-world coding problems you can run into when you try to do things the right way.  At the end of the day, I really had to choose the best of a bad set of options frankly – I created a result object that has a boolean member (succeeded) and a string (extra message).  My business calls return this object. Now, I’m not even sure if this is the best possible design.  Raymond has also suggested that there may be problems with this – for example, say you have an error message that indicates that the method failed with a true value for success. This can be fixed by making the boolean read only, based on some internal logic (like error message null) but then the message always has to indicate an error. 

    -Brendan

  • ASP.NET Development "Bitness" on Windows XP 64 Bit Edition

    I hope the title of this post isn’t too confusing; this is not about developing for 64 bit ASP.NET, it’s about how to develop ASP.NET apps when running under 64 Bit windows.  I’ve recently been tasked to do a bunch of 3D studio animation and to support this project, I was ordered a new workstation. Yeah, I’m not really bragging, but it’s a dual zeon, blah blah whatever, I’m not a hardware guy.  Poor me, right?

    Anyway, I went ahead and had it equipped with XP Pro 64 Bit, assuming this would be the best for graphics-intensive apps.  Now, I’m not so sure this was the greatest idea, since as Audodesk/Descreet doesn’t appear to have a 64 bit version of 3D Studio, but I’ve got it installed so I’m sticking with it.

    Today, I ran into my fist big hangup with 64 bitland.  I had a really hard time opening a Visual Studio ASP.NET project from source safe.  Specifically, opening the web project.  Just wouldn’t open.  Now since this can be a problem on a new system, I set the project type to “Local” to just get the dang thing to open up, and did manage to squeeze out a build. 

    When I went to the server to test, I got

    Service Unavailable

    ...on my local web server (running on my workstation).  You know, that brilliant IIS error in the big bold <H1> in your web browser.  So,  I re-booted the server, and I still got this error! After much looking around, I finally found some great information over on David Wang’s blog, that told me just what to do, here’s an excerpt from his post, HOWTO: Diagnose one cause of 503 Service Unavailable on IIS6:

    The reason why you are getting this event is straight forward:

    * On 64bit Windows, the "bitness" (i.e. 32bit or 64bit) of a process must match the bitness of the DLLs loaded by that process. In other words, a 64bit EXE can only load 64bit DLLs, and 32bit EXE can only load 32bit DLLs.
    * By default, IIS6 on 64bit Windows runs with 64bit W3WP.EXE worker processes
    * .NET Framework 1.1 has ASP.Net implemented through 32bit ISAPI DLLs.

    What is happening when you install .NET Framework 1.1 on IIS6 on 64bit Windows is that while IIS6 runs W3WP.EXE as 64bit, you are configuring it to load some 32bit ISAPI DLLs. This does not work and leads to the event log entry. Since the ISAPI DLLs are loaded for every request, this failure immediately happens again and again, thus triggering the "Rapid Fail Protection" health monitoring check of IIS6. This leads to this Application Pool being taken offline and a 503 Service Unavailable response being sent.

    One way to fix this issue is to make IIS6 run W3WP.EXE as 32bit, which allows the 32bit ISAPI DLLs installed by .NET Framework 1.1 for ASP.NET to load and run inside of it. This is done by running the following commandline:
    CSCRIPT %SYSTEMDRIVE%\Inetpub\AdminScripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1

    This fix worked great.  I also love his use of the word “Bitness!” I think this will become common vernacular as more of us get on 64 bits.. Anyhow, just wanted to relay the fix, and the warning, and I hope you can read this … see these fonts, they were typed in 64 bit.  

    -Brendan

  • Welcome Scott Bellware

    I'd like to welcome to CodeBetter.Com our most recent addition, Scott Bellware.  I hope the following stuff about him is true... I found it on line, and you never know if you can trust what you find out there on the internets.  :)
    Scott Bellware Bio
    Scott is a .NET software professional living and working in Central Texas. He works primarily with C# focusing on Web applications, object persistence, reuse, and software quality. He has been awarded MVP for C# 2004, 2005.

    He has given talks for .NET user groups on web templating, object-relational persistence, and test-driven development. He spoke on these subjects at DevTeach 2003 and 2004.

    He is a founding officer of the Austin .NET User Group and helped to establish the International Association of Software Architects. He acted as chairman of the INETA Speaker Committee between 2003 and 2005.
    You can also find out more about him over at http://www.bellware.net. His CodeBetter.Com blog can be found at http://codebetter.com/blogs/scott.bellware.

    Welcome on board Scott!

    -Brendan
More Posts