# 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]  | 
# Sunday, November 11, 2007

Here's a good reason not to use untyped datasets.  I was tasked with hiding a radio button on a webform depending on the SkuType of the product.  Unfortunately I have no idea if the web application, let alone the web service it uses for data access, returns the SkuType already.  The web service just returns a bunch of untyped datasets as raw strings.  To actually figure out what each web service call is returning I have to look at each sproc's SELECT statement.

If I had some hint in the code of what the expectations of the form of data, I could at least grep for SkuType.  As it is now I may be adding it to an existing sproc, thus unknowingly duplicating logic.  I guess my only alternative is to export out all sprocs to a script and then grep the script for SkuType.

Sunday, November 11, 2007 10:17:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, November 05, 2007

I did a commit from my home PC tonight where I don't have CCTray installed.  I don't have it installed largely because I'm usually disconnected from work VPN and CCTray will just show up as a gray ball in my systray.

After committing my changes I felt pretty nervous because there were a lot of new files added to the project and I wasn't using VisualSVN which would normally make sure these get committed.  After checking my email and not seeing any commit mails from the SVN server - I got very nervous.  Did my commit go into a black hole?  Is SVN down, did the build server crap out, is email down?  Ah!

I finally figured out Outlook wasn't synchronizing my Checkins mail folder for whatever reason.  In a panic I went and installed CCTray, and found that my commit was just fine and SVN didn't send it into a black hole after all.

I didn't realize that working with a continuous integration server with almost instant feedback is so tightly integrated into everything I do development wise.  What really surprised me was how much I use commit emails.  I didn't like commit emails when I first started the practice (they were a manual affair then), but now that they get auto generated upon commit using CaptainHook and use the SVN commit description, I've grown to really like them.

Now I can sleep soundly knowing that my code is safe.

Monday, November 05, 2007 7:25:26 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, November 04, 2007

After using DisplayFusion for the past week at work I came home to use my PC and discovered that something was missing.  As it turns out I heavily use the "drag maximized window" feature of DisplayFusion at work, and probably won't ever use another OS/PC without this feature (assuming I have more than one monitor).  It almost seems like a bug that Vista doesn't natively support this feature out of the box.

Sunday, November 04, 2007 8:16:30 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 01, 2007

In my previous post I assumed that I would need to explicitly load my child objects through my service and provide a finer grained service interface to support that model.  After digging through Udi Dahan's blog posts again I found a very relevant post about using a fetching strategy to specify how deep you want the object model to be for any specific request.  By being able to specify a fetching strategy in the consumer code I can return the proper size object graph without making my service interface chatty.

This does leak some of the service logic into the client code, but really I'm OK with that.  The alternative is to explicitly call each service method which I think is harder to maintain and makes the object model pretty difficult to use. 

After using Mule ESB at my last job I've found it kind of hard to go to plain old web services.  I really like the messaging paradigm and separation of concerns an ESB provides.  Now if I could just find the SVN repository for NServiceBus.

Thursday, November 01, 2007 5:43:20 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

I downloaded the NHibernate VS2005 plugin and started to use it - its very similar to the Hibernate support built into Eclipse.  Unfortunately after playing around with it for about 20 minutes I realized my data model (in the DB) was complete poo and the plugin wasn't built to handle legacy databases, which I completely understand because that's where the majority of NHibernate's complexity lies IMO.

I really don't want the crappy data model to leak into my object model - even though it would be super easy and fast to "whip it out" using the plugin or another code generator.  I'm kind of stuck on what to do right now.  Part of the problem is I'm not sure I have time to "do it right." I have a hard deadline looming from a 3rd party that can't budge.


I think I may start out modeling my object model from scratch, which isn't too bad with Re# installed.  Then from there start manually mapping some of this stuff to the existing sprocs or creating some new views.  I also have the problem that this will all be serialized and sent over a web service and/or NServiceBus, so I'm not sure how to handle relationships.  Probably in most cases I'll just have IDs of the FKs and then explicitly make another fetch from the service since lazy loading is pretty much out of the question.

Thursday, November 01, 2007 3:17:34 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |