• Castle monorail logging with windsor

    Using Castle monorail with windsor, I setup the logging facility and followed the IoC of concept parameters for optional components. I noticed the base Controller had Logger property and assumed that windsor would handle it from there. However, my controller always had the NullLogger as the ILogger property. The base Controller class doesn’t have a setter for the Logger property. Still not sure why that is, also the property is not virtual. I should submit a patch for this. Anyway, one solution is to create a new property Logger in your own Controller with a getter and setter thus allowing windsor to set the Logger when the Controller is created.

    public abstract class BaseSiteController : ARSmartDispatcherController
    private ILogger _logger = new NullLogger();

    public new virtual ILogger Logger {
    get { return _logger; }
    set { _logger = value; }
  • SharpDevelop project templates

    I wanted to create castle project template for SharpDevelop, I ran into a few issues, some I found a way to fix, some I didn’t.

    One thing that I needed to do was add a project reference to a dll that was not in the GAC, to do this the HintPath attribute can be used on the Reference element.

        <Reference Include=“Castle.Core” HintPath=“c:\castlebin\Castle.Core.dll”/>

    Secondly, I wanted to set the debug options to allow cassini debugging. I found a way to set these options but I didn’t find a way to dynamically insert the project name/dll into the command line options. In the PropertyGroup element you can add the following to set these options. Note the ${ProjectName} string is not replaced with the project name.

            <StartProgram>c:\program files\cassini\CassiniWebServer2.exe</StartProgram>
            <StartArguments>C:\Documents and Settings\Dusty\My Documents\SharpDevelop Projects\${ProjectName} 8080 “/${ProjectName}”</StartArguments>

    So I guess there are still two main problems with this setup. First you have to know the path of any dll’s that are not installed in the GAC. And if you want to reference the project name in the debug options, it doesn’t look like there is a way to do that. But for setting up personal project templates these things may be useful.

  • Setting build numbers with Nant

        <h3> Setting build numbers with Nant </h3> I wanted something that would update the version number of my builds from within Nant. I found that using some of the built in functions of Nant I could get what I wanted without too much work. Nothing really exciting here, but a couple of notes. First the version numbers stored in the meta data limit the size to uint16.maxvalue - 1 so the value must be less then 65534. As such I could not use the format yyyyMMdd as I wanted to, so I ended up using days since 1/1/2000. Secondly, when loading the file with loadfile I needed to mark the encoding as UTF-8 so that the file would be writen back out in a usable form. Anyway, here's the nant code I ended up using.<br /><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.major"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.minor"</span><span class="attr"> value</span><span class="kwrd">="9"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.build"</span><span class="attr"> value</span><span class="kwrd">="${timespan::get-days(datetime::now() - datetime::parse('01/01/2000'))}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.revision"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.version"</span><span class="attr"> value</span><span class="kwrd">="${build.major}.${build.minor}.${build.build}.${build.revision}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">foreach</span><span class="attr"> item</span><span class="kwrd">="File"</span><span class="attr"> property</span><span class="kwrd">="assemblyinfofile"</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">in</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">items</span><span class="attr"> basedir</span><span class="kwrd">="${project.root}"</span><span class="kwrd">&gt;<br /></span>      <span class="kwrd">&lt;</span><span class="html">include</span><span class="attr"> name</span><span class="kwrd">="**\AssemblyInfo.cs"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;/</span><span class="html">items</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;/</span><span class="html">in</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">do</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span><span class="kwrd">="${path::get-file-name(assemblyinfofile)}"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">loadfile </span><span class="attr">file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="attr">property</span><span class="kwrd">="assemblyinfofile.content"</span><span class="attr">encoding</span><span class="kwrd">="utf-8"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">regex</span><span class="attr"> pattern</span><span class="kwrd">="&amp;quot;(?'version'\d+\.\d+\.\d+\.\d+|\d+\.\d+\.\*)&amp;quot;" </span><span class="attr">input</span><span class="kwrd">="${assemblyinfofile.content}"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="kwrd">&gt;</span>${string::replace(assemblyinfofile.content, version, build.version)}<span class="kwrd">&lt;/</span><span class="html">echo</span><span class="kwrd">&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span>="<span class="attr">-</span><span class="kwrd">&gt;</span> Updated version from ${version} to ${build.version}"<span class="kwrd">/&gt;<br /></span>  <span class="kwrd">&lt;/</span><span class="html">do</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">foreach</span><span class="kwrd">&gt;</span></pre><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Monorail: Exception Handlers: Flash and Redirect

    e setting up exception chaining on monorail, I wanted to use the Flash properties to store the LastException for next request, an error page. This by default doesn't work if the exception happens outside of the Castle.MonoRail.Framework.MonoRailHttpHandler.Process method. This is because the Flash variables don't get saved until after this method. One note here, the Process method is wrapped in a try, finally block and the Flash properties will be saved in the case of an exception on the Process method, some additional checking in the exception handler may be needed to catch this. Anyway, I added the following line to my last handler and the Flash properties are working great.<br /><br /><span style="font-family: Courier New;">context.Session[Flash.FlashKey] = context.Flash;</span><br /><br /> Secondly, I wanted to redirect to different views based on the exception, which I wasn't able to do. The reason was that the asp.net framework noticed the exception an handled according, not what I wanted. The way around this is to clear the error using the Server.ClearError() method before redirecting.<br /><br /><span style="font-family: Courier New;">context.UnderlyingContext.Server.ClearError();</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Using nant and tallow to create usable WIX component.

        <p>Creating installer for web application can be a pain, but using tallow and an nant script element can make things a lot easier.</p>
        <p>Once my nant script was building my solution and web project with all the needed output files I begin to setup automating the build of the WIX component for the web application.</p>
        <p>As you know tallow output is not usable as is, some custom handling needs to be done. I've found the script element of nant to work well for this. I've also created a new class library project to keep the script block small, and keep the source in a project. I've included the class library in the solution build. </p>
        <p>Nant target:</p>
        <!-- code formatted by http://manoli.net/csharpformat/ -->
        <pre class="csharpcode">&lt;property name="wix.websitefragment.file" value="${build.output.temp}\website-fragment.wsx"/&gt;<br />&lt;target name="buildwebsitewsx" depends="solution"&gt;<br />    &lt;mkdir dir="${build.output.temp}"/&gt;<br />    &lt;exec program="${wix.bin}\tallow.exe" workingdir="${build.output.temp}" output="${wix.websitefragment.file}"&gt;<br />        &lt;arg value="-d &amp;quot;${compile.output.webapplication}&amp;quot;"/&gt;<br />        &lt;arg value="-nologo"/&gt;<br />    &lt;/exec&gt;<br />    &lt;script language="C#" verbose="true"&gt;<br />        &lt;references&gt;<br />            &lt;include name="${compile.output}\InstallHelper.dll"/&gt;<br />        &lt;/references&gt;<br />        &lt;imports&gt;<br />            &lt;import namespace="InstallHelper"/&gt;<br />        &lt;/imports&gt;<br />        &lt;code&gt;<br />        &lt;![CDATA[<br />        public static void ScriptMain(Project project) {<br />            string file = project.Properties["wix.websitefragment.file"];<br />            new FixTallow(file, "My.ComponentGroup.Name").UpdateFile();<br />        }<br />        ]]&gt;<br />        &lt;/code&gt;<br />    &lt;/script&gt;<br />&lt;/target&gt;<span class="kwrd"></span></pre>
        This calls the tallow application on the directory where the web application is built. Then loads and calls the InstallHelper.dll to modify the tallow output into something more usable. <br /><p>The FixTallow class loads the tallow output into an XML document and takes the following actions; adds a component group, creates guids for the components, renames the directory id's and changes the directoryRef element to point to the INSTALLDIR.</p><p>The component group needs to be created so a reference can be added to the main WIX file. This is because tallow creates a component for each directory (or each file) and because I don't want to update the main WIX file every time there is a directory added or removed from the web application. The group name is passed the the constructor of the FixTallow class. </p><p>FixTallow also renames the directory id's so that I can reference them if needed from the main WIX file, however if the directory is removed or renamed, the main WIX file will need to be updated. Also, the root DirectoryRef element is changed to reference INSTALLDIR which needs to be set in the main WIX file. This is a good idea as it allows the installation directory to be changed when installing.</p><p>FixTallow.cs</p><pre class="csharpcode"><span class="kwrd">    public</span><span class="kwrd">class</span> FixTallow<br />    {<br /><span class="kwrd">  private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _filename;<br /><span class="kwrd">    private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _componentGroupName;<br />        XmlDocument _document = <span class="kwrd">new</span> XmlDocument();<br />        XmlNamespaceManager _manager;<br />        XmlElement _compGroup;<br /><br /><span class="kwrd">   public</span> FixTallow(<span class="kwrd">string</span> filename, <span class="kwrd">string</span> componentGroupName)<br />        {<br />            _filename = filename;<br />            _componentGroupName = componentGroupName;<br /><br />            _manager = <span class="kwrd">new</span> XmlNamespaceManager(_document.NameTable);<br />            _manager.AddNamespace(<span class="kwrd">string</span>.Empty, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />            _manager.AddNamespace(<span class="str">"ns"</span>, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />        }<br /><br /><span class="kwrd"> public</span> FixTallow UpdateFile()<br />        {<br />            _document.Load(_filename);<br /><br />            AppendComponentGroupElement();<br /><br /><span class="kwrd">        foreach</span> (XmlElement element <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Component"</span>, _manager))<br />            {<br />                element.Attributes[<span class="str">"Guid"</span>].Value = Guid.NewGuid().ToString().ToUpper();<br />                AppendComponentToGroup(element.Attributes[<span class="str">"Id"</span>].Value);<br />            }<br /><br />            ChangeDirectoryRefId();<br /><br />            UpdateDirectoryIds();<br /><br />            _document.Save(_filename);<br /><br /><span class="kwrd">      return</span><span class="kwrd">this</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> UpdateDirectoryIds()<br />        {<br /><span class="kwrd">            foreach</span> (XmlElement directory <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Directory"</span>, _manager))<br />            {<br /><span class="kwrd">                string</span> directoryName = (directory.Attributes[<span class="str">"LongName"</span>] == <span class="kwrd">null</span>)<br />                                           ?<br />                                       directory.Attributes[<span class="str">"Name"</span>].Value<br />                                           :<br />                                       directory.Attributes[<span class="str">"LongName"</span>].Value;<br />                directory.Attributes[<span class="str">"Id"</span>].Value = directoryName + <span class="str">".Dir"</span>;<br />            }<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> ChangeDirectoryRefId()<br />        {<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment/ns:DirectoryRef/@Id"</span>, _manager).Value = <span class="str">"INSTALLDIR"</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentToGroup(<span class="kwrd">string</span> componentId)<br />        {<br />            XmlElement componentRef = _document.CreateElement(<span class="str">"ComponentRef"</span>, _manager.DefaultNamespace);<br />            XmlAttribute componentRefId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            componentRefId.Value = componentId;<br />            componentRef.Attributes.Append(componentRefId);<br />            _compGroup.AppendChild(componentRef);<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentGroupElement()<br />        {<br />            _compGroup = _document.CreateElement(<span class="str">"ComponentGroup"</span>, _manager.DefaultNamespace);<br />            XmlAttribute compGroupId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            compGroupId.Value = _componentGroupName;<br />            _compGroup.Attributes.Append(compGroupId);<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment"</span>, _manager).AppendChild(_compGroup);<br />        }<br />    }</pre><p>The main WIX file needs to include a few things for this to work. First, it much have a diretory element with INSTALLDIR as it's Id. Second, a ComponentGroupRef element pointing the component group name specified in the FixTallow constructor needs to be included in the Feature element.</p><pre class="csharpcode">...<br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="TARGETDIR"</span><span class="attr">Name</span><span class="kwrd">="SourceDir"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="ProgramFilesFolder"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="INSTALLDIR"</span><span class="attr">Name</span><span class="kwrd">="myapp"</span><span class="attr">LongName</span><span class="kwrd">="MyApplicationName"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">Feature</span><span class="attr">Id</span><span class="kwrd">="Complete"</span><span class="attr">Level</span><span class="kwrd">="1"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">ComponentGroupRef</span><span class="attr">Id</span><span class="kwrd">="My.ComponentGroup.Name"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Feature</span><span class="kwrd">&gt;</span><br />...</pre>Lastly, the tallow output needs to be passed to the candle and light applications when building the msi file with something like this:<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\candle.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="Main.wsx website-fragment.wsx"</span><span class="kwrd">/&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\light.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="-out MyApplication.msi Main.wixobj website-fragment.wixobj"</span><span class="kwrd">/&gt;</span></pre><span class="kwrd">There was a lot of setup here, but once completed changes can be made to the web application without modifying the WIX files, resulting in an up to date MSI on each build.</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Adding wix support for VS.NET

     the .xsd files in the wix\doc directory to C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas directory.<div style="clear: both; padding-bottom: 0.25em;"></div>
  • Validate if checkbox is checked using really easy validation

    / Needs Really easy validation.js script & prototype.js /

    function validateIfChecked(v, e) {
    var cbId = e.getAttribute(‘usecheckbox’);
    if (cbId != ‘undefined’) {
    if ($(cbId).checked) {
    var validationType = getValidationType(e);
    return !Validation.get(‘IsEmpty’).test(v) && Validation.get(validationType).test(v)
    else {
    $(e).value = ‘’;
    return true;
    return true;

    function getValidationType(e) {
    var classes = e.className.split(‘ ’);
    for (i = 0; i < classes.length; i++) {
    if (classes[i].indexOf(‘validate-checkbox-’ >= 0))
    return classes[i].replace(‘validate-checkbox-’, ‘’);
    return ‘validate-number’; // default;

    Validation.add(‘validate-checkbox-required’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-number’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-digits’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-alpha’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-alphanum’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-date’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-email’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-url’, ‘Please provide a valid value when checked’, validateIfChecked);
    Validation.add(‘validate-checkbox-validate-currency-dollar’, ‘Please provide a valid value when checked’, validateIfChecked);

    Realy Easy Validation