NetDug Notes: Validation in .Net


Last week at NetDug there were two presentations on Domain Centric validation in .Net. Having used the following list of validation frameworks in the past I found it was interesting that neither of the two presenters used any of these frameworks.

Attribute Based Validation


Say what!? Why are we reinventing the wheel again. But through the group discussion I, and I think the group, came to the following conclusions:

  • Attribute based validation, like those frameworks above, are great for property validation but can break down in very complex validation scenarios, such as those scenarios that may required Repository access
  • While most frameworks have extension points for advanced scenarios using them can bloat your domain model
  • The best use for attribute validation is when I want to verify my data constraints way, way before my database

Service Based Validation

In the second presentation Cory gave a quick version of his Portland Code Camp talk and introduced a service based validation framework that injects a chain of validation classes for a given domain object. I thought it was a nice solution and the code camp project are worth checking out if you'd like to learn more

In short the goals or this validation framework where the following:
  • Keep validation logic outside of attributes and large xml files that are not refactorable
  • Return faults from WCF Service as soon as possible
  • Retrieves validations classes through StructureMap by loading all instances of a specific type validator, keeping domain classes decoupled from validation logic
  • Having separate validation classes allows for complex, cross object based validation
  • Can be used in tandem with an attribute based validation solution by simply creating a validation service that  runs the attribute based validation.
These presentations were timely as this week I've come to the point where I have to begin working on a validation solution for a CMS Framework we've had out on Google Code for some time.  My only problem is that I want to allow my users to define validation rules dynamically at run time and both of these solutions are design time implementations. 

Oh well, off to create another wheel.

Get back to work...

Tonight I let the TV stop on VH1 playing the last part of 8 Mile. I left it on because sometimes down here in Colombia its nice to listen to a show in English that's not CNN.

I've enjoyed the movie in the past and I was reminded again tonight just how much I like the ending.  If you don't remember it at the end of the movie Jimmy, played by Eminem, emerges as the triumphant hero from the local rap battle. Outside the Detroit venue already drunk with victory Jimmy's crew is ready to go paint the town red. But with an unexpected dose of reality Jimmy turns down his friends and walks away back down the dark street to complete a second shift at work.

For some reason I like endings like this that leave you a little bit let down or take a sudden tragic twist just before the credits roll. It reminds us that sometimes real life can be hard and even sad. In this case it also reminds us that even after a big victory there's still work to be done. Getting that big recording contract still requires a lot of steady progress and the occasional big break.

Professionally it reminds me that the end of a project isn't always the time to take a rest and party. Sometimes we just need to finish up and then get back to work on the next thing... a lesson I really need to take to heart in the next 2 weeks.

Reverse Proxy for Team City 4.0

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I was setting up a new instance of Team City 4.0 on our development server at Six Day Tech today and ran into an all too frequent problem with our Apache Reverse Proxy  server.

 

I basically accepted the defaults during the Team City install which gave me a local URL of something like: http://dev:8081/ . I then set up a proxy rule in our Apache configuration to proxy http://dev.ourdomain.com/TeamCity to the http://dev:8081 address on the dev server using the following proxy settings.

   1: #TeamCity
   2: ProxyPass /TeamCity http://dev:8081
   3: ProxyPassReverse /TeamCity http://dev:8081

(*Additional proxy settings not specific to Team City have been omitted)

These settings allowed me to get to the TeamCity login page but the style sheet and JavaScript references where all pointed to the root, e.g. /css/style.css instead of to /TeamCity/css/style.css. The login page was actually displaying a missing JavaScript error and even if I could have gotten by with the missing styles I knew this was no good.

 

Because we are running all our traffic through our proxy server through HTTPS and only have one IP address we couldn't use an Apache Virtual Host and a URL like https://TeamCity.ourdomain.com.  So my choices where to add some sort of URL Rewrite rule to our proxy server or to get TeamCity to run from a sub directory on the host server. I chose to look at how to get TeamCity to run from a sub directory. This was consistent with some of the other sites were are running through our proxy server so I thought it would be no problem... until I discovered that TeamCity is running inside a Tomcat server.

It took me  about an hour of searching the net to come up with clear instructions on how to create a virtual directory in Tomcat, called a context so I'll just cut to the chase of how I finally set it up.

  1. Stop the TeamCity Service
  2. Locate and the server.xml file in <TeamCity_Install_Dir>/conf directory. (For me that was in D:\Programs\TeamCity\conf
  3. Open the server.xml file in Notepad
  4. Find the first 'Host' section. Mine looked like this.
  5.    1: <Host name="localhost"  appBase="webapps"
       2:             unpackWARs="true" autoDeploy="true"
       3:             xmlValidation="false" xmlNamespaceAware="false">
  6. Inside the Host section added the following Context element to create the sub directory.  Where the value for 'docBase' points back to the TeamCity install directory.
  7.    1: <Context path="/TeamCity"
       2:                                 docBase="D:\Programs\TeamCity\webapps\ROOT"
       3:                                 debug="1"
       4:                                 reloadable="true" > </Context>
  8. Restart the TeamCity service and made sure it worked locally from http://dev:8081/TeamCity
  9. Updated the Apache Proxy settings to include the sub directory and restarted the Apache Proxy server.
  10.    1: #TeamCity
       2: ProxyPass /TeamCity http://dev:8081/TeamCity
       3: ProxyPassReverse /TeamCity http://dev:8081/TeamCity

 

Now I get a pretty URL to my TeamCity site and the benefits of having a secure connection without having to setup Tomcat to communicate in HTTPS.

Response to "The Nichols Personal Development Plan"

Scott Nichols created a  post this week on ElegantCode.com about the Importance of  a Personal Development Plan for software developers.  Scott really wanted feedback on his post and since he's a good friend or mine and all around good guy I figured I'd oblige him and throw up a quick response. 

Having worked at the same company with Scott for 6 of the last 8 years. I'm going to have to agree with his assessment that many developers don't have a personal development plan and that can make it difficult to market yourself or to find a new job when your current skills are no longer needed. I think this can be even worse at large companies where developers tend to specialize in very specific skills more than they do at smaller shops.

I agree with Scott that reading books and blogs and playing with beta software are important parts of a personal development plan but I think Scott missed, or assumed we know, the first and most important part of a personal development plan.  That is defining what you want to develop into.

 

Every Plan Needs a Target

Before anybody can create a development plan or reading list they need to be able to answer the question, "What type of developer do I want to be? 1, 3, 5 or even 10 years from now?  Identifying this target directs every other decision you make concerning YOUR Personal Development Plan.

image

 

If you want to be a web developer than you should structure your learning around those technologies that help you develop better in that arena. If you want to be a mobile device guru or move your way into supervision or project management then your going to study and develop a completely different set of skills. And you need to pursue projects and employment opportunities that help you reach those goals.

I think of this process as reverse engineering my career, kind of like Reflector for my life. I define where I want to be and then write out the steps that I think I will need to take to get me there. This also lets me take a minute to evaluate if I have the time, resources and opportunity to reach the target I have set.  My wife and I go through a similar process with our family a couple times a year and often I find myself laying out the steps to reach a target and realizing that I don't have the time, resources and sometimes desire to do what it actually takes to reach the goal and I change my targets as a result. 

The most important thing about setting a target for your personal development plan is that it helps you avoid the unfortunate possibility of waking up one morning five years form now and asking yourself, "How the heck did I become a test engineer for smart clients when what I really wanted to do was web development? This sucks!"

 

The Responsibility of Senior Developers and Management

One thing I love about Scott is that he really has a heart for helping other developers continually learn.  He's been on the leadership team of NetDug for as long as I can remember.  Those of us who are senior developers and management or even just have our own personal development program together owe it to our friends and colleagues to share our plan with them and hold them accountable for creating and executing on their own plan.

 

... okay that's all for now. Scott, I'll comment on your book list later.

Free Ajax Updating Logo's

I just used this site, http://www.ajaxload.info/, a couple of times today for creating Ajax update animations for use with our YUI Update Panel. The site was pretty quick and much easier than me coming up with something myself.

Very Simple MySql Backup Script for Windows 2008

I just setup the following super simple backup script on our Six Day Development server. I know it needs more features. Perhaps the ability to rotate through the backup files. But shouldn't that be the job of my offsite backup job and not my local dump routine? Anyway, here its.

@echo off

:: Usage: CommandFilename [BackupType]

date /T
time /T
echo.

::
:: Set mysqldump parameters
::
Set mysqluser=root
Set mysqlpassword=xxxxxxxx
Set mysqlHost=localhost 
Set mysqlOptions=--opt

::
:: Set backup file location
::
Set backupDir=D:\Data\Backups\MySql\

Set baseFileName=%backupDir%mysqlbackup_%date:~10,4%%date:~4,2%%date:~7,2%

set backupFileName=%baseFileName%.sql
Set zipFileName=%baseFileName%.zip


:: -----------------------------------------------------------------------------
set mysqlcmd=mysqldump %mysqlOptions% --all-databases --user=%mysqluser% 
          --host=%mysqlHost% --result-file=%backupFileName%
echo.
echo Performing mysqldump of %mysqlhost%
echo Dump command: %mysqlcmd%
echo.

:: Execute the backup
%mysqlcmd% --password=%mysqlpassword%
if %ERRORLEVEL% NEQ 0 goto errors


::-----------------------------------------------------------------------------
:: Zip up the backup file using 7zip and remove the initial backup file

7z a -tzip %zipFileName% %backupFileName%
if %ERRORLEVEL% NEQ 0 goto errors

:: Delete the .sql file
del %backupFileName%
if %ERRORLEVEL% NEQ 0 goto errors

echo.
echo Backup complete!
echo.
goto finish


REM: How to use screen
:usage
echo.
echo Usage: Backup sript for MySql
echo.
goto done


REM: error handler
:errors
echo.
echo WARNING! Error(s) were detected!
echo --------------------------------
echo Please evaluate the situation and, if needed,
echo restart this command file. You may need to
echo supply command parameters when executing
echo this command file.
echo.
goto done


REM: finished execution
:finish
echo.
echo Script execution is complete!
:done
date /T
time /T
echo.

Google Apps for Domains ... does not like system account

We ran into an interesting error today trying to send email from our company web site using our Google Applications for Domains smtp server.  In short here was the code we were using to send email from our contact form:

public static void SendMail(string to, string subject, string body)
        {
            var m = new MailMessage()
            {
                Subject = subject,
                Body = body
            };
 
            m.To.Add(ConfigurationManager.AppSettings["ContactToAddress"]);
            
            var s = new SmtpClient();
            s.EnableSsl = true;
            s.Send(m);
        }

We had our Google SMTP settings setup in our web.config file as follows:

<add key="ContactToAddress" value="info@mydomain.com" />
.
.
.
<system.net>
  <mailSettings>  
    <smtp from="system@mydomain.com" deliveryMethod="Network">
      <network host="smtp.gmail.com" port="587" userName="system@mydomain.com" 
password
="######" defaultCredentials="false"/>
    </smtp>
  </mailSettings>
</system.net>

This should be a no-brainer. We've had our Google Apps account for several months and have had no issues. So we know our DNS settings are correct and up to date.  But once we deployed this code to our server we started receiving a fail messages from Google:

PERM_FAILURE: Message rejected.  
See http://mail.google.com/support/bin/answer.py?answer=69585 for more information.

 

All the mail messages would show up in the system mail account sent items folder but would then get rejected as spam before being sent to the info distribution list at the same domain.

But wait it gets weirder the same email message form within the Gmail interface would be sent just fine! 

 

It was clear that something was causing Gmail to reject a message sent from and too itself.  Eventually we changed the user who we were using to send the email from 'system' to 'webcontact' and the messages started being delivered successfully. Yet another reason to hate spammers for making my life harder than it needs to be.

Self Signed SSL Certificates in IIS7

Today I had my first "Aha!" moment with IIS7... well almost.

I've been using IIS7 locally on my Vista development machine for some time now but I must say I've been missing the familiarity I've gained with IIS6 over the last several years. Now before somebody starts telling me about all the great new features in IIS7, I love the way IIS7 allows more configuration in side my web.config files for ASP.Net and I'm ecstatic about how it supports the new ASP.Net MVC framework. It's just that I haven't had much time to really play with these new features.

Well, today I was working on a WCF application that I initially wrote on IIS 6. When I was running some local integration tests I was reminded that my services were configured to run over HTTPS. Oh well, I thought off to create yet another self-signed certificate for IIS but before I went off down my usual path I decided to do a quick Google search on "self signed ssl iis7". To my delight I pulled up a blog post by Scott Guthrie on this exact topic. Come to find out IIS7 came with a UI tool for creating self signed certificates in IIS. Yes, I thought, one less command line for me to remember. I quickly ran through the certificate wizard and added the certificate to my web site reran my integration test and BANG...everything exploded.

Come to find out the self signed certificate wizard in IIS 7 only registers the certificate a CN equal to the host name. So while the hostname I was using to access my site was local.onfile.com the certificate would only register as my computer name, alhanson.

Oh well, so much for this new feature, back to the trusty selfssl.exe tool from the IIS6 resource kit. Which looks to be working well for me now.

99Designs.com Logo Contest

I am in the process of starting up a new consulting and software company with my friend, and now business partner, Lance. We're both definitely not designers and when want to keep startup costs low so when it came time to create a new logo for our company we launched a design contest on 99Designs.com

We're really happy with the number and the quality of the designs we've seen so far. If you need some design work 'crowd sourced' you should check it out.

Also, check out our design contest and let us know what you think of the submissions.

Later!

ReSharper 4.0 Beta

Finally after much waiting ReSharper 4.0 has finally gone beta...wait a minute haven't those other guys already shipped a production .Net 3.5 compatible version. Oh well, I love ReSharper and I'm excited about the update.

«July»
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678