# Thursday, December 20, 2007

I encountered a really annoying bug in the SQL Server SMO scripting library today.  Once you script out a single "DROP" script the internal scripter is left in a bad state and starts throwing NullReferenceExceptions on any subsequent call to the Script method.  I haven't found a good way around this yet.  Unfortunately the only reference I can found about this issue confirms the bug but nothing else.  Hopefully this will be fixed in SQL Server 2005 SP3, because it sure isn't fixed in SP2.

Thursday, December 20, 2007 8:43:15 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, December 14, 2007

Data binding DateTime fields in MonoRail is pretty powerful and flexible, but not really straight forward.  Most of the time you can just provide the domain object propery as an argument to the a form helper method, but with DateTime's split across multiple select boxes this doesn't work when you post back to your controller method.  To get DateTime's to work across several HTML select fields you need to explicitly provide the selected value like so:

$Form.Select("billing.accountExpiration", $billing.accountExpiration.Month, [1..12], "%{tabindex='11'}")
$Form.Select("billing.accountExpiration", $billing.accountExpiration.Year, [$DateTime.Now.Year..2011], "%{tabindex='12'}")

Friday, December 14, 2007 6:50:05 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

I asked the alt.net group what issue/feature tracking software everyone would recommend, and thankfully I got a lot of responses about what people are using or have used in the past.  Really useful stuff.  It would take an individual years to glean this kind of first hand experience.  Here's a summary of recommendations (good and bad):

  • TRAC - Python based OSS app. It seemed a lot of people have used this.  Most people think it's OK, but the consensus is that it's kind of "wonky" at times.  The UI isn't particularly pleasant, but Ayende did create a simple Winform UI for it at one point - not sure it still works or how well.
  • Mingle - Developed by ThoughWorks.  ROR app.  The UI is pleasant and customizable.  The pricing is different, it seems you pay monthly.  Wave of the future, especially for software that gets released frequently (permanent beta)?  Compared to the competition this appears to be a rather expensive option - but possibly worth it.
  • FogBugz - The UI is pretty simple/clean, and has a good dashboard.  I liked the fact that is contained "evidence based tracking" which sounds really smart and useful - as long as everyone enters their actual time on a task accurately.  Phil Hack said, "...FogBugz is hands down awesome. Anyone that disagrees with me, you're wrong. End of story."
  • StoryVerse - MonoRail reference project or real OSS based project?  The code AND the UI look really clean.  I'm not sure if this is still active or how full featured it is, but it definitely looks promising.
  • Gemini - Got some mixed reviews, but I think most people gave it a +1.  It looks like a lot of companies are using this one.  Integrates great with SVN.  The screenshot of the home page reminded me of Jira.
  • Elementool - Fairly cheap.  Free version fields.  From Donn, "Unintuitive and just a hassle to use. Never integrated it with anything though. I wouldn't want to. I just want to STOP using this product."
  • Lighthouse - Looks like a hosted ROR app?  From Brian, "It has rough edges in some areas, but overall is a very nice interface, and you can use email to create and comment on issues.  It only has ONE status field (which at first seemed limiting, but then I realized was liberating - at least for this project).  If all you are doing is tracking open items (for example on a maintenance project) it may be all you need."
  • TargetProcess - ASP.NET agile management tool.  It will manage bugs, features, and support tickets.  It integrates with SVN.  What's cool is that it uses NHibernate to data access, so it appears you could use any RDMS that NHibernate supports.
  • BugTracker.NET - This is a very simple OSS ASP.NET app, but one look at the code you'll run screaming. 
  • AxoSoft - TODO: more info
  • MS Project Server - It's "enterprisey".
Friday, December 14, 2007 8:15:46 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, November 28, 2007

Today I discovered that in Monorail you must add an HTML name attribute to each element you want the SmartDispatchController to autowire for controller method parameters.

Without any name attributes on my emailAddress and password text boxes, the values were null that were passed into my controller method (BTW - isn't that a nice clean controller method?):

public void CreateAccount(string emailAddress, string password, string returnUrl)
{
    UserServiceResponse response = userService.CreateNewAccount(emailAddress, password);
    if (response.HasErrors)
    {
        Flash.Add("Summary", response.ErrorMessages);
        RedirectToAction("New", "ReturnUrl=" + returnUrl);
    }
    else
    {
        CancelView();
        Session[AuthenticationFilter.UserKey] = response.User;
        Redirect(returnUrl);
    }
}

 

Adding the "name" HTML attribute made the values auto populate as needed:

 

<input id="emailAddress" name="emailAddress" type="text" tabindex="1" />

Wednesday, November 28, 2007 11:53:29 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 26, 2007

If you need to override the Prototype submit behavior in MonoRail's FormHelper.FormTag, you will need to use on_submit instead of onSubmit.  This isn't obvious since every other parameter seems to match up to the JavaScript libraries params.

With that out of the way I can hook my custom validation and display logic for a non-domain object ala Billy McCafferty's post.

Here's an example to override the onsubmit behavior:

$Form.FormTag("%{action='login', on_submit='false'}")

Monday, November 26, 2007 11:24:56 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, November 21, 2007

I was banging my head against the wall today trying to figure out a compatible way between Windows XP and Vista to detect if MSVCRT 8 runtime was installed using NSIS.  I wanted to do this because I want to avoid downloading that component if the user's PC already has that version installed; this is especially important for update scenarios.  Finally I figured out a very simple way to do it, just wildcard check for the existence of a specific versioned directory in the WinSxS folder:

; IsMsvcrt8Installed
;
; Checks target machine for MSVCRT 8.0.50727.762 runtime installed in Windows
; SxS DLL cache.
;
; Returns 1 if found, otherwise 0
Function IsMsvcrt8Installed

  ; we can assume version because SxS directory is version specific
  FindFirst $R1 $R0 "$WINDIR\WinSxS\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.762*"
  
  ${If} $R0 != ""
    DetailPrint "MSVCRT 8.0 is installed."
    StrCpy $R0 1
  ${Else}
    DetailPrint "MSVCRT 8.0 is not installed."
    StrCpy $R0 0
  ${EndIf}
  
  Push $R0
  
FunctionEnd

Wednesday, November 21, 2007 1:04:40 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 19, 2007

I created a modified version of CCTray to be able to right click and deploy the last build to an environment. 

ModifiedCCTray

CCTray just silently runs the NSIS installer for the project, but I'm going to change this so that the installer UI will show up - but only show the progress bar.  The workflow is:

  1. Make local change.
  2. Commit to SVN.
  3. CruiseControl.NET automatically kicks off a build.
  4. A couple minutes later I can right click in CCTray and deploy to Dev or Test environments.
  5. Send out an email to QA.
Monday, November 19, 2007 8:14:34 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, November 17, 2007

If you need to get the password of a protected Access MDB, Access PassView is free and works.

Saturday, November 17, 2007 4:31:42 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 12, 2007

There has been a lot of buzz over the past few days about ASP.NET MVC allowing developers to create RESTful URLs.  This turned out to be very good timing since I was implementing RESTful URLs without first realizing it in MonoRail last week.

I had to give a business partner two links to our new online service, one for each screen mode the partner's web device supported: splitscreen and fullscreen.  This got me thinking about the URLs I was providing, since I was essentially etching the URL in stone; I wanted to make sure they looked professional and provided maximum flexibility in the future.  It also got me wondering if I couldn't add additional information into the URL; information that in the past I would have stuck in a cookie or in a session. 

At first I put this extra data in the session, but then I started thinking about: session time out, load balancing, SQL Server DB, and scalability. Cookies might be better, but then I thought how the browser on these devices immediately asks you if you want to store a cookie - bad first impression.  It seemed the answer was to use the querystring and pass state around from one page to the next on the querystring, but I hated the idea of passing around a few values on every single page request.  This seemed fragile and made every page URL ugly and long.

I already knew that you generally want to use directories, or resources, over querystring parameters for web search engine optimization, but then I realized that using resources instead of querystring parameters is also more organized and user friendly.  Here's an example of two URLs, one using a querystring, and the other using a REST style resource URL.

http://sneal.net/fullscreen/categories/category1/page1

http://sneal.net/categories.rails?screenMode=fullscreen&category=1&page=1

I think its pretty obvious that the first (REST style) URL is much better for several reasons:

  • Easier to read, it's essentially just a directory path.
  • Easy to remember, it avoids strange symbols and is shorter.
  • Provides a nice structure to the data: categories -> 1st category -> 1st page.
  • It's discoverable.  Its pretty obvious what you can type in to go to page2 etc.

Another benefit is that links into your web application aren't tied to a particular technology or platform.  I've already experienced this at GalleryPlayer when we wanted to change some static HTML content into dynamic ASP.NET pages - external URLs weren't just looking for a resource, but they were explicitly looking for a static HTML page.  If we had implemented REST style URLs from the very beginning using URL rewriting, any external links could have been using a technology agnostic URL instead of a specific one tied to static HTML.

For example, I can point people to http://sneal.net/blog/somepost, rather than http://sneal.net/blog/blog.aspx?post=somepost.  If later on I decided to switch from dasBlog to a ROR based blog engine running on Linux, I could do that without anyone being the wiser.  The blog.aspx link would be much more difficult to change the underlying technology to ROR since the link includes the resource 'blog' and the view implementation type, 'aspx'.

Lets not forget what URL stands for: Uniform Resource Locator. In the end the consumer of your data shouldn't really care how you produce the results, whether you're using ASP.NET, MonoRail, ROR, PHP, or JSP.  The only thing the consumer should care about is the data your service, or web page, is providing - and where to find it at.  With an MVC framework like MonoRail, ROR, or ASP.NET MVC, URL routing couldn't be easier.

As K Scott Allen said, "The [ASP.NET] MVC framework is, I believe, about putting control in the hands of a web developer. Control over the routing of HTTP requests to components. Control over selecting the view. Control over state management, and control over the outgoing HTML."  I couldn't agree more.  URL routing/rewriting gives you a flexible abstraction layer between your URLs and your resource implementations.

In my next post I hope to show how I avoided session state and cookies by using REST style URLs with MonoRail.

Monday, November 12, 2007 7:25:08 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  |