Tuesday, January 21, 2014

ASP.NET MVC, TypeScript, Azure Website and Git Deploy

The Issue

The issue and the workaround in this post applies to:

  • Visual Studio 2013
  • ASP.NET MVC using at least one TypeScript file
  • Azure Website with git deploy
  • Sites build and deployed before kudu issue 721 was resolved

Building a web site with ASP.NET and TypeScript targeting Azure Website I ran into an issue after I added the first TypeScript file and tried to deploy the web site using git deploy. It would fail with the following error message:

C:\DWASFiles\Sites\typescripttest\VirtualDirectory0\site\repository\TypeScriptHTMLApp1.csproj(67,3): error MSB4019: The imported project "D:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\TypeScript\Microsoft.TypeScript.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

The root cause for this is that the file Microsoft.TypeScript.targets file is not yet available using git deploy for Azure Websites.

The issue that I ran into is documented and discussed in a few places, e.g.

Here is my workaround that solved the issue for now. Rumors has it that Microsoft is working on a proper solution for the issue.

Note that the workaround does not require a custom “deploy.cmd” file which I felt was a plus despite having creating custom deploy scripts for other projects and other reasons.

The Workaround

The workaround is based on making the msbuild task and the TypeScript compiler available when the msbuild script (aka solution file and project files) are executed.

In my repository I created a folder 3rdparty in parallel to the solution file.

Next I created a subfolder typescript-sdk and copied the content of “C:\Program Files (x86)\Microsoft SDKs\TypeScript” into “3rdparty\typescript-sdk”. The folder contains a file tsc.exe. Make sure this is version 0.9.1.1. This version worked for me. Apparently there are other versions out there. For example version 0.9.5.0 is reported to create an error.

I also needed the msbuild task. For that I created a subfolder typescript-task and copied the content of “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript” into “3rdparty\typescript-task”.

The next two steps required editing the file “Microsoft.TypeScript.targets” located in “3rdparty/typescript-task” and the ASP.NET MVC project file. I won’t detail these changes here as all of this workaround is available in a repository.

With this workaround I have the same behavior for Azure Website’s git deploy as I have locally building from Visual Studio 2013. To use a TypeScript file, all I have to do is adding the file, reference the resulting javascript in the appropriate place in my views or layouts, commit and push. No further steps required.

Once the issue is resolved, all I have to do is undo the changes in the project file and remove the folders “3rdparty\typescript-sdk” and “3rdparty\typescript-task” and everything else is back to normal.

This workaround should also be applicable for scenarios where you already have a custom deploy script. The workaround does not require any changes to custom deploy scripts.

All of the source code is available in a sample project at https://bitbucket.org/ml_agileutilities/typescript-sample. There is a branch with a version that allows reproducing the problem. There is a second branch that demonstrates that the workaround fixes the issue. If you want to try out either scenario create an Azure Website and have it use git deploy from one the respective branch.

Credits

I’d like to thank Thiago Almeida and David Ebbo, Microsoft, for their awesome support in finding and testing this workaround.

Although I didn’t need a custom deploy script in the end, I would also like to thank Amit Apple for his very helpful description of how to create custom deploy script for Azure Websites.

Monday, July 15, 2013

No Split Window for TypeScript?

In case you installed TypeScript for Visual Studio 2012 and are wondering why you are not getting the split window for a TypeScript file: Check whether you have installed “Web Essentials 2012” as well. The latter gives you the split windows.

We had a couple of cases in one of the teams I’m working with where installing Web Essentials resolved the issue.

Friday, May 24, 2013

Xamarin Studio: Hello, world! fails to build

I just purchased, installed and tried out Xamarin Studio. My motivation is that I want to try out this C#-based approach towards developing applications for Android.

Not that I want to move away from Visual Studio. I’m just working through a few examples and wanted to rule out VS as an influencing factor.

Problem is that the Hello World example already failed. The error message was “The “Aapt” task failed unexpectedly.” And there was also a “System.InvalidOperationException: Sequence contains no elements” and an error code “MSB4018”. Here is a screenshot:

image

To solve it launch the Android SDK Manager. In my case it showed that there was a new update for the Android DSF Platform-tool and also showed that the Android SDK Build-tools were not installed. I just left all checked/unchecked as it was and installed what was checked. Admittedly not very selective but it did the trick. Now it’s building.

Thursday, May 23, 2013

Visual Studio Image Library

Just tried to locate the Visual Studio Image Library. I couldn’t find it. Various sources suggest to locate the file VS2010ImageLibrary.zip. This doesn’t exist on my machine, though.

It turned out that I never had Visual Studio 2010 on this machine, only Visual Studio 2012 has been installed. It appears as if VS2012 doesn’t install it by default.

However, you can download the VS2012 Image Library here. Hopefully this post helps you saving some time.

Saturday, May 04, 2013

WiX: Installing Files to Public Documents Folder

A few days ago I stumbled over the problem of installing files into the “Public Documents” folder using the Windows Installer Toolkit (WiX). Although the different bits a pieces are available somewhere on the internet I couldn’t locate a single source that describes a complete solution.

On Windows based systems each user has their own personal folder but there is also a folder called “Public Documents”. For the task at hand, I wanted to install a few sample text files into a subfolder of the public documents folder using WiX. For this example I used Visual Studio 2012 (Professional Edition or better is sufficient) with the Visual Studio extension installed by WiX 4.0.

Let’s start with the wizard for the WiX setup project:

image

As the name for the setup you can pick anything you like. In this case I chose “Acme.Setup”. The resulting project looks very simple. It has no references and only a single WiX script file in it:

image

The content of Produce.wxs is very basic (Note that the first few digits of all GUIDs in this post are replaced with the string ‘YOURGUID’. You need to replace the GUIDs with your own to make it work):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Product Id="*" Name="Acme.Setup" Language="1033" Version="1.0.0.0" Manufacturer="" UpgradeCode="YOURGUID-269e-4795-97d7-a392d75749fb">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate />

        <Feature Id="ProductFeature" Title="Acme.Setup" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="Acme.Setup" />
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
            <!-- <Component Id="ProductComponent"> -->
                <!-- TODO: Insert files, registry keys, and other resources here. -->
            <!-- </Component> -->
        </ComponentGroup>
    </Fragment>
</Wix>

Obviously, we now need to change this to add some files. So let’s pick a text file from a different project in the same solution. In this case I created a C# library projects called Acme.Lib and added one simple text file. We can ignore the default class ‘Class1’ that is generated in the Acme.Lib project. It is not relevant for this blog post. Here is what the solution looks like now:

image

The content of the file readme.txt and it’s name are irrelevant as well. Choose what works best for your case.

Next we need to make sure that the installer script knows about the text file and where it is located. The first option is to use your knowledge about the location of the two projects, Acme.Lib and Acme.Setup. So you could change the file Product.wxs as follows:

<Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
        <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
        <!-- <Component Id="ProductComponent"> -->
            <!-- TODO: Insert files, registry keys, and other resources here. -->
      <Component Id="ReadmeFile" Guid="{YOURGUID-994F-49C0-A7AC-53D1571A295A}">
         <File Id="readme.txt" Name="readme.txt" Source="..\Acme.Lib\readme.txt"></File>
      </Component>
        <!-- </Component> -->
    </ComponentGroup>
</Fragment>

Some points of interest. First of all we need to add a new <Component> to the script. Your installer can consist of thousands of components if you wish. In this case I’m only adding one component with an Id and a GUID. Again, please note that I have replaced the first few digits of the GUID with ‘YOURGUID’. You need to replace all GUIDs in this example with newly generated GUIDs anyways to make it work.

Inside of the component I place a <File> tag with the Id, the name and the Source of the file. The Id needs to be unique within the installer while the name is the name that the file will have once installed. The ‘Source’ attributes tells the WiX toolset where to find the file so it can be included into the installer. Note that in contrast to some other installer tools sets the build of the installer will fail in case the WiX toolset can’t find the file.

At this stage there one additional tweak that we have to do to compile this build script successfully. We need to edit the 'Manufacturer’ attribute at the beginning of Product.wxs. Here are the first four lines (Note that ‘Manufacturer’ has been set to ‘Acme’):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Product Id="*" Name="Acme.Setup" Language="1033" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="YOURGUID-269e-4795-97d7-a392d75749fb">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

If you now build your solution it should build without problems.

At this stage all you have is an installer that installs into the into a subfolder in Program Files. It works but it is not what we want. So let’s have a look how we can change that.

The trick is to add some WiX specific extensions. This can be accomplished by adding a reference to the installer project, ‘Acme.Setup"’ in this example. The dialog box looks as follows and we want to add a file called ‘WixUtilExtension.dll’:

image

Adding this reference enables support for functionality that allows installing into the “Public Documents” folder.

The way we can use this is by adding a property reference with the Id ‘WIX_DIR_COMMON_DOCUMENTS’ as follows:

<Product Id="*" Name="Acme.Setup" Language="1033" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="YOURGUID-269e-4795-97d7-a392d75749fb">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

   <PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS"/>

   <Feature Id="ProductFeature" Title="Acme.Setup" Level="1">
        <ComponentGroupRef Id="ProductComponents" />
    </Feature>
</Product>

WiX will set the property ‘WIX_DIR_COMMON_DOCUMENTS’ to the correct path for the “Public Documents” folder when the installer is executed. We don’t have to worry about that.

Now this property has been referenced we can use it to specify where we would like to install our readme file. For that we first need to change the <Directory> tag content as follows:

<Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="WIX_DIR_COMMON_DOCUMENTS">
         <Directory Id="ACMEDOCUFOLDER" Name="Acme Documentation">
         </Directory>
      </Directory>
      <Directory Id="ProgramFilesFolder">
            <Directory Id="INSTALLFOLDER" Name="Acme.Setup" />
        </Directory>
    </Directory>
</Fragment>
Note the additional directory tag with the Id ‘WIX_DIR_COMMON_DOCUMENTS’. I left the other directory tag in place. We don’t need it for the example in this blog post. For yuor actual installer you may want to use it to place binary files into a folder inside of “Program Files”.

The next change you have to make is adding a new component group that installs into the WIX_DIR_COMMON_DOCUMENTS folder. Here is the snippet that achieves this:

<Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
        <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
        <!-- <Component Id="ProductComponent"> -->
            <!-- TODO: Insert files, registry keys, and other resources here. -->
      <!-- </Component> -->
   </ComponentGroup>
   <ComponentGroup Id="DocuComponents" Directory="ACMEDOCUFOLDER">
      <Component Id="ReadmeFile" Guid="{YOURGUID-994F-49C0-A7AC-53D1571A295A}">
         <File Id="readme.txt" Name="readme.txt" Source="..\Acme.Lib\readme.txt"></File>
      </Component>
   </ComponentGroup>
</Fragment>

Note that again I left the default component group untouched (Id=”ProductComponents”). Instead I created a new component group and gave it the id ‘DocuCompoents’. Then I moved the component ‘ReadmeFile’ from the former to the latter.

We are not quite finished yet. One item is missing. The installer does not yet know that it should include this new component / component group into the installer. So here is what we need to do to accomplish that:

<Product Id="*" Name="Acme.Setup" Language="1033" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="YOURGUID-269e-4795-97d7-a392d75749fb">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

   <PropertyRef Id="WIX_DIR_COMMON_DOCUMENTS"/>

   <Feature Id="ProductFeature" Title="Acme.Setup" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
      <ComponentGroupRef Id="DocuComponents" />
   </Feature>
</Product>

Once you build and execute the resulting installer then the result will look as follows:

image

And this screenshot demonstrates that we have accomplished what we wanted: We successfully installed a folder and a file into the “Public Documents” folder.

If you’d like the full source code of this solution please send an email to manfredmlange at gmail dot com.

Happy coding!

Sunday, April 07, 2013

Outstanding Support

I had an issue with JIRA/Greenhopper today and contacted Atlassian’s support at 08:12 am (it’s Sunday here). At 08:17 am I had a message from a human being saying that he was investigating. Communication was flowing and at 08:34 am the issue was resolved. Total time spent: 17 minutes from reporting the problem.

The way I have experienced working with Atlassian they will probably say this is just the normal way they operate. And I agree they have always been very easy to work with.

I’m mentioning it here since I think their support can serve as an example for a lot of other companies. I trust that you can easily create your own list of those who can improve.

Bottom line: Today I experienced excellent support from Atlassian … as usual. Thank you, Nick!

Saturday, March 16, 2013

Ubuntu 12.10 in Virtual Box on Windows 7

Today I spent some time to get Ubuntu 12.10 installed as a virtual machine using VirtualBox. That as such wasn’t the challenge. For example a pretty good description can be found at Windows Seven Forums.

Getting the guest additions installed was the problem. Quite a few sources suggested to use VirtualBox’s menu “Devices” – “Install Guest Additions…” However, what was offered as a solution didn’t work in my case. Note that I’m not a Linux or VirtualBox expert, so my lack of knowledge might have been the reason.

After quite some search I found a very good description on Sysprobs. Dinesh did a fantastic job with his blog post. Now I can resize the VM’s window any way I like and the VM’s screen adjusts properly. Almost seamless integration Nice!

Thursday, December 06, 2012

csUnit Interim Release 2.8.4723

We have made available a new release of csUnit. This is an interim release with the version number 2.8.4723 and can be found on GitHub.

This release requires .NET 4.5. It doesn’t have an installer and no Visual Studio plugin. The download is a zip file that you need to extract into a folder then run csUnitRunner from there. If you encounter an issue please log the issue here with detailed info about your environment, the version of csUnit you are using and steps to reproduce.

We intend to create a WiX based installer next.

For more info about csUnit check out csUnit’s homepage.

Saturday, September 15, 2012

Free Azure Storage Explorers

When working with Azure you’ll eventually work with storage (blob, table, …). Wouldn’t it be nice if you had a simple way to browse through the content of your Azure storage? And wouldn’t it be nice if you also use the same tool to access your local Azure storage emulator?

Here are two tools that do exactly that. And in addition they are free.

The first tool is “Azure Storage Explorer” provided by Neudesic. This tool is open source, hosted on Codeplex. It is licensed under the “Common Development and Distribution License (CDDL)”. I’ve used this tool for several months now and was very valuable, allowing moving files, copying files, creating containers, deleting containers, etc. You can set up all your storage accounts, including local development storage and then access it without having to enter credentials again. It remembers your access keys.

The second tool is “CloudBerry Explorer for Windows Azure” provided by CloudBerry. This tools is available as freeware. I just downloaded it and played with it for a little while, so can’t provide any detailed insights yet.

Having a tool for browsing your Azure storage content is a handy tool for developers as well. That’s why I thought it would be worth mentioning here.

Happy coding!

Tuesday, September 11, 2012

NullReferenceException in Html.ValidationSummary()

I was implementing a view using ASP.NET MVC, MVC 4 in this case but I suspect the version is irrelevant. I received a NullReferenceException when any validation failed, ie the model state was invalid.

The stack trace was close to useless and looked similar to the following:

at ASP._Page_Views_Issue_Create_cshtml.Execute() in c:\projects\au\AgileTraxx\Web\Views\Issue\Create.cshtml:line 26
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.StartPage.RunPage()
at System.Web.WebPages.StartPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)

Line 26 which the stack trace referring to was:

Html.ValidationSummary();

This wasn’t much help either. It took me a lot of experimentation to find out that in this particular case the property Model of the view was null. Once I set the model for this view, it all went nicely.

Note that not always it is obvious from scanning the code that one didn’t set the model for a view. Therefore I’m blogging my experience here and to give the recommendation that should you encounter the same or similar behavior, to the following:

  1. Set a breakpoint on the line where the exception is thrown.
  2. Debug the application
  3. When the breakpoint is hit, enter “Model” in the “Immediate Window” in Visual Studio and check whether it outputs “null”.

Happy coding!

Saturday, April 21, 2012

ASP.NET: Base Directory and Developer Tests

Assume that in your ASP.NET application you need to access a file that is part of the deployed web site. On the other hand you would like to also run some developer tests.

The way I like to organize developer tests is putting them in a separate project and a separate assembly. For example for an ASP.NET project “MySite” I would have a second project called “MySite.Tests”. In the test project I then reference the “MySite” project which gives me direct access to all code inside of “MySite”. Typically give all projects a strong name and therefore can make internals of “MySite” visible to code in “MySite.Tests” by placing the InternalsVisibleToAttribute on the “MySite” assembly.

The challenge now with accessing the file is that depending on whether they are run from within an ASP.NET server (IIS or WebDev.WebServer) or within a unit test runner, finding the root folder (or base directory) can be tricky in some cases.

For example we could use a solution based on the MapPath method of the HttpContext.Current.Server object. This is described in more details in an answer on StackOverflow and works when an HttpContext is available. When the same code is run in a unit test runner HttpContext.Current is null (Controller.HttpContext in MVC), so this solution wouldn’t work.

The solution that I have chosen and that works so far is based on the application domain. The following code is all that is required and it works in both IIS, WebDev.WebServer as well as when executed within a unit test runner:

var domainRoot = AppDomain.CurrentDomain.BaseDirectory;
var configFile = Path.Combine(domainRoot, Common.DbSettingsFile);

Happy coding!

Wednesday, April 18, 2012

MVC 3 and "Microsoft JScript runtime error: 'jQuery' is undefined"

In the course of working on an ASP.NET MVC 3 based project I updated jQuery via NuGet. This worked as expected, except for one view where the application then reported the error "Microsoft JScript runtime error: 'jQuery' is undefined".

The resolution was to check the Java Script references in the view that had the problem. It was also necessary to updated _Layout.cshtml as follows:

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <title>@ViewBag.Title</title>
   <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
   <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
   <script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")" type="text/javascript"></script>
</head>
<body>
   ...
</body>
</html>

After these changes it worked like a charm.

Monday, April 16, 2012

WiX 3.6 Beta Behavior When Building

Just noticed an interesting behavior of a solution that contains about 20 projects and one WiX project. It would fail when using “Rebuild All” with some strange error in a wxs-file that compiled fine previously. When using “Rebuild” on the WiX project it would build just fine. This was reproducible at that point.

To resolve it I restarted Visual Studio and all was fine again. I couldn’t reproduce the issue. I guess that it was some add-in that got a pointer or reference mixed-up.

My setup is: Visual Studio 2010 Professional, ReSharper, dotCover, AnkhSVN, WiX 3.6 beta.

Monday, April 09, 2012

More On Closing WCF Connections

Some time ago I blogged about how to implement a WCF client in C# using VS2008. In particular I mentioned that implementing the client side code with a using statement may potentially lead to problems as – against their own advice – Microsoft chose to implement the Dispose() method of class System.ServiceModel.ClientBase<TChannel> in such a way that it can throw exceptions. (Dispose() implementations should not throw exceptions.) This implementation that violates Microsoft’s own guideline is also described in an article where Microsoft recommends not to use “using” when working with WCF clients.

In this blog post I’ll revisit the options for handling client side code. In the meantime I’ve moved to VS2010 and I’m using .NET 4.0. To get started let’s recall the code from back then:

var client = new PondServiceClient();

try {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.IsFrozen(_pondNameTextBox.Text) ?
      " is frozen." : " free of ice.");
   client.Close();
}
catch (CommunicationException ex) {
   // Handle exception
   client.Abort();
}
catch (TimeoutException ex) {
   // Handle exception
   client.Abort();
}
catch (Exception ex) {
   // Handle exception
   client.Abort();
}

So the canonical form (also described on MSDN) is to check for CommunicationException and TimeoutException. If the service defines Service Fault's you may want to catch those exceptions (FaultException<T>) as well.

It would be great if there were ways to fix this problem as there is one more issue with using the canonical way. Imagine you have lots of touch points between your client and a service. Wouldn’t it be nice if you could avoid all that try-catch business? It looks like a lot of code duplication after all.

Marc Gravell’s Solution

One possible solution is described by Marc Gravell in his blog. He makes extensive use of generics. Using Marc’s solution the above code would look something like this:

using (var client = new Proxy().Wrap()) {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.BaseObject.IsFrozen(_pondNameTextBox.Text) ?
      " is frozen." : " free of ice.");
}

I agree with Marc that this solution would be safe, easy to call and would eliminate the code duplications. His solution calls the service client’s Dispose() method (ClientBase<TChannel>.Dispose()) but wraps it inside a try-catch construct. If an exception is thrown by the Dispose() it is swallowed.

The first concern I have with this solution is that it doesn’t call Abort() and Close() respectively as per Microsoft’s recommendation. It just swallows the exception that might be thrown by the Dispose method.

The second concern I have is that the expression “new Proxy().Wrap()” doesn’t appear very intuitive and easy to understand. This is probably a minor point as with more experience in using this solution one can will become used to it.

Jeremy Jameson’s Solution

Another option can be found at Jeremy Jameson’s blog. Jeremy suggests to derive a class and add a new implementation for Dispose(). To stay with the pond service example, that new class would then look as follows:

public class PondServiceClientWithDisposeFix 
   : PondServiceClient, IDisposable {
   void IDisposable.Dispose() {
      if (this.State == CommunicationState.Faulted) {
         this.Abort();
      }
      else if (this.State != CommunicationState.Closed) {
         this.Close();
      }
   }
}

With this class in place the implementation of the client side could then be re-written as follows:

using(var client = new PondServiceClientWithDisposeFix()) {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.IsFrozen(_pondNameTextBox.Text) ?
      " is frozen." : " free of ice.");
}

Very elegant, easy to understand and correct by the looks of it. I was tempted to use this option if it wasn’t for a concern that I have with this. With reverse engineering it is possible to find out what ClientBase<TChannel>.Dispose() does. When Jeremy wrote his blog (March 2010) the Dispose() implementation simply called Close().

My concern is that the new implementation doesn’t call the base class implementation at all. By the way the PondServiceClient class is declared partial so the Dispose method could probably be implemented as an extension method as well. As long as the base class implementation is not called, this couldn’t resolve my concern, though. What if Microsoft at any time decides to change the implementation of ClientBase<TChannel>.Dispose()? This kind of change typically happens – thanks, Murphy! – we we expect it the least.

Even if the implementation was never changed, there is a small thing that concerns me. Microsoft has included a little note regarding the use of the ClientBase<TChannel>.State property:

image

So, Jeremy’s solution probably will work. But it is against Microsoft’s recommendation of not using the State property. In particular I get nervous because of the term “race condition”. If problems occur because of race conditions these are typically hard to find and resolve, therefore a very expensive type of issue.

Therefore if we want to follow that recommendation we are back to square one. We would have to surround the use of ClientBase<TChannel> derived objects with boilerplate try-catch statements.

Using Anonymous Methods

Basically the problem is that in order to remove the code duplication a pair of code snipped has be executed before and after the service invocation. Proper handling of communication objects almost sounds like an aspect… so for a moment I even considered looking into libraries like DynamicProxy2 or Ninject. On second thought, though, these felt like overkill for something that appears very simple.

Enter anonymous methods. Basically you can pass a block of code to a different method that does things, executes the block of code, maybe does other things, then returns. How does this apply to the code snippet for the pond service example above. Let’s try to highlight with colors what the boiler plate code is and what the code is that is different:

image

The code within green rectangles is the actual implementation while the code in the orange rectangles is the boilerplate code. Note, how the orange pieces surround the second green piece.

The way to simply this is using a class that works like an interceptor. I implemented a class called ServiceClientInterceptor and it’s main method now looks as follows, again using green and orange rectangles as above:

image

As you can see the green rectangle simply invokes the function that was passed in. With the ServiceClientInterceptor in place you can now write the client side code as follows:

using (var client = new PondServiceClient()) {
   new ServiceClientInterceptor(client).Invoke(() => {
      _pondStatusMessage.Text = _pondNameTextBox.Text +
         (client.IsFrozen(_pondNameTextBox.Text) ?
         " is frozen." : " free of ice.");
   });
}

Line 2 in this example show the beginning of an anonymous method that is passed in as a parameter to the Invoke() method. The cool thing is that inside of the anonymous method you have access to the variables that are accessible at the point of where the anonymous method is defined. It is not limited to where the intercept invokes the execution of that anonymous method.

As a result you can now wrap service invocations with try-catch statements without code duplication.


With this general concept working there are of course further questions that I haven’t covered in this blog post. For example, what if you want reuse the service client for further invocations in the same using block? What if you had multiple service clients that are used within the same anonymous method? I’ll leave these to you for further explorations as there several options in each case.

The solution presented here meets the following requirements:

  • Allows use of using construct
  • Properly closes or aborts WCF connections depending on exception thrown
  • Avoids code duplication
  • Does not make use of ClientBase<TChannel>.State property as per Microsoft’s recommendation

To complete this blog post, below is the full source for the ServiceClientInterceptor class. In that case I have changed the parameter type of the Invoke method to Action. In the screenshots above I still used ServiceMethod which had an identical definition but was the result of earlier experimentation. The Action delegate encapsulates a method that has no parameters and does not return a value. As always you are welcome to use this code at your own risk.

If you know of a solution better than any of the ones mentioned in this post I'd like to hear from you. Happy coding!

public class ServiceClientInterceptor {
   public ServiceClientInterceptor(
         ICommunicationObject serviceClient) {
      _serviceClient = serviceClient;
   }

   public void Invoke(Action func) {
      try {
         func.Invoke();
         _serviceClient.Close();
      }
      catch (CommunicationException ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
      catch (TimeoutException ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
      catch (Exception ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
   }

   private ICommunicationObject _serviceClient;
}

Saturday, March 03, 2012

VisualBasic .NET and C#

In case you need to compare language features of VB.NET and C#, you might find the following URL helpful. It contains a quite detailed comparison of both languages.

Thursday, January 19, 2012

ReSharper Not Showing Any Tests?

Version 6.x of ReSharper appears to have a tendency to forget about some tests in a solution once a while (at least once a day in my case). When using “Run All Tests From Solution” it can happen that it shows only a subset of them. In extreme cases it can happen that no tests are shown in the “Unit Tests Session” window.

I’ve noticed that the behavior becomes better after removing all other extensions. I don’t feel this is very practical. The extensions I use are AnkhSVN and Powertools and I’m using Visual Studio 2010 on a 64 bit Windows 7. All software are the latest released versions and has the most recent patches or service packs applied.

I reinstalled everything but that didn’t change the behavior. When I run all unit tests outside of Visual Studio, e.g. using csUnit, it is all fine.

One way to resolve this is following these five steps:

  1. Close Visual Studio
  2. Delete the _ReSharper.* folder that is located in the folder containing your solution
  3. Start Visual Studio
  4. Reopen your solution
  5. Select “Run all tests from Solution” from the ReSharper menu

Since once in a while the web deployment functionality requires a restart of Visual Studio as well, I now have two triggers that may force me to restart Visual Studio.

Yes, it is annoying but at least now I have found this work around. Maybe it helps saving you some grief as well.

Wednesday, December 28, 2011

Ninject, Interception and out/ref arguments/parameters

While implementing an aspect using Ninject along with its Ninject.Extensions.Interception I found that it wouldn’t work with arguments (parameters) that are ‘out’ or ‘ref’ (‘out’ is just a special case of ‘ref’ really). I found a temporary solution at CodeProject and in parallel submitted an issue on Github for the Ninject guys to have a look at. I expected this to take a few weeks or even months to be resolved. But they surprised me positively. Support for out/ref arguments/parameters was implemented within 5 hours. Remo, do you sleep at all?

Remo Gloor, one of the Ninject project contributors, responded with saying that the feature will be included in Ninject 3.0. I checked and he had just committed the needed changes. Thank you, Remo, for the fast turn around! To confirm I updated my local sources from Github, compiled them and it all worked as expected. Sweet!

According to Remo, support for out / ref parameters / arguments will only be available when you use DynamicProxy2. If you want to make use of it prior to the 3.0 release of Ninject just pull the latest set of sources and build it yourself. Happy coding!

Saturday, December 24, 2011

Razor, MVC3, Client-Side Validation and Multiple Submit Buttons

In a details view for creating a new model object I wanted to replace the Cancel link with a Cancel button. I wanted both to be buttons as I felt that to be more consistent. I didn’t realize that I would be up for a surprise when I placed two submit buttons into a single form since, of course, not matter what button I would click I would always end up in the same controller method. It was even worse. As client-side validation was enabled, clicking the Cancel button would perform client-side validation and not even make it to the server.

I googled and found a couple of ideas for how to handle multiple submit buttons. For example one type of suggestions is based on implementing a class derived from ActionMethodSelectorAttribute, for example here or here. Another type of suggestions is based on implementing a class derived from ActionNameSelectorAttribute, for example here.

I couldn’t get any of these to work the way I wanted. I found that they would work only when I disabled client-side validation or JavaScript on the client altogether. Only in these cases, and by giving the submit button a name using the ‘name’ attribute, would the button value be included in the request. Therefore this was just a partial solution as I wanted to support both scenarios (JavaScript disabled, JavaScript enabled). I tried the actionmethod attribute on the input element but either I used it incorrectly or the handling of this new HTML 5 element is not yet correctly handled by either the browsers or MVC on the server. I didn’t investigate this in more detail.

Here is the solution that worked for me.

First I implemented a JavaScript function which I placed at the end of the view (.cshtml):

<script type="text/javascript">
   function OnFormButtonClick(action, validate) {
      if (!validate) {
         document.forms[0].noValidate = true;
         document.forms[0].action = '' + action;
         document.forms[0].submit();
      }
}
</script>

The first parameter of this short method is the name of the action (controller method) to be invoked on the server side while the second parameter determines whether or not to validate on the client side. Of course the latter would only kick in when JavaScript is enabled on the client side. If you want to use multiple submit buttons in several place you may want to put this function in a shared file such as ‘_Layout.cshtml’ or similar.

With the JavaScript function in place I then added the two submit buttons to the Razor view (HTML form) as follows:

<p>
   <input type="submit" value="Create" name="button"
    onclick="OnFormButtonClick('Create', true);" />
   <input type="submit" value="Cancel" name="button"
    onclick="OnFormButtonClick('Cancel', false);" />
</p>

This would now work with JavaScript enabled on the client. How about the scenario when JavaScript was disabled? In that case submitting the form would always submit to the same action (‘Create’ in my case) no matter what button was clicked. Some server side code was required to distinguish this. This is the point I added a class which is derived from ActionNameSelectorAttribute:

/// <summary>
/// Attribute that helps MVC with selecting the proper method when multiple submit buttons
/// exist in a single form.
/// </summary>
/// <remarks>The implementation is partially based on  </remarks>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiSubmitButtonAttribute : ActionNameSelectorAttribute {
   public override bool IsValidName(ControllerContext controllerContext, 
                                    string actionName, 
                                    MethodInfo methodInfo) {
      // Implementation derived from:
      // http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx
      if (controllerContext.RequestContext.HttpContext.Request["button"] != null) {
         // JavaScript disabled.
         return controllerContext.RequestContext.HttpContext.Request["button"] == methodInfo.Name;
      }

      return actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase) 
         || actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase);
   }
}

The first if()-statement in this implementation yields to true only if JavaScript is disabled on the client. In that case the request contains the information about which submit button was clicked and this can be compared to the name of the controller method (bear with me for a little longer to see how this will work). Having this new attribute available I was now able to add it to the controller methods handling the two cases (‘Create’ and ‘Cancel’):

[HttpPost]
[MultiSubmitButton]
public ActionResult Create(FormCollection collection) {
   // TODO: insert your 'Create' logic here
   return RedirectToAction("Index");
}

[HttpPost]
[MultiSubmitButton]
public ActionResult Cancel() {
   return RedirectToAction("Index");
}

When MVC tries to route the action to a controller method it will now also invoke the IsValidName method in the MultiSubmitButtonAttribute class. The two scenarios now work as follows:

Case 1 - JavaScript enabled: The little JavaScript function is executed on the client side and an appropriate action will be requested. The action is simply routed to the controller method of the same name. Depending on the second parameter of the call to the JavaScript function (and subject to server side settings in web.config) client-side validation is executed or not.

Case 2 – JavaScript disabled: The client includes the name of the submit button and the MultiSubmitButtonAttribute helps MVC to select the correct controller method.

Extending HtmlHelper to Simplify View Implementation

There is a way to simplify the view implementation by extending the HtmlHelper class as follows:

public static class HtmlHelperExtensions {
   public static MvcHtmlString SubmitButton<T>(this HtmlHelper<T> helper, string value, string action, bool validate) {
      return new MvcHtmlString(String.Format("<input type=\"submit\" value=\"{0}\" name=\"button\" onclick=\"OnFormButtonClick('{1}', {2});\" />", value, action, validate ? "true" : "false"));
   }
}

With this the submit buttons can be coded like this:

@* Namespace of the HtmlHelper.SubmitButton() implementation: *@
@using Web.Helpers; 

... other code for Razor based view

<p>
   @Html.SubmitButton("Create", "Create", true)
   @Html.SubmitButton("Cancel", "Cancel", false)
</p>

Note that although it appears as if the first two parameters here are duplicated, they are not. The first parameter is the label that appears on the submit button and you may want to localize it. The second parameter is the name of the action which you typically don’t want to change. Even if everything is in the same language (e.g. English) they can be the same but don’t have to.

Automatically Injecting JavaScript

So far the solution requires manually adding the OnFormButtonClick() function either to the Razor view or to have it in some shared file. I would like to remove this by making the HtmlHelper.SubmitButton<T>() implementation a little smarter:

public static class HtmlHelperExtensions {
   public static MvcHtmlString SubmitButton<T>(this HtmlHelper<T> helper, string value, string action, bool validate) {
      var javaScript = string.Empty;
      const string functionName = "_OnFormButtonClicked";
      if (!helper.ViewData.ContainsKey(functionName)) {
         helper.ViewData.Add(functionName, true);
         const string linefeed = " \n\r";
         // Inspiration for the following JavaScript function from:
         // http://www.javascript-coder.com/html-form/html-form-action.phtml
         javaScript = "<script type=\"text/javascript\">" + linefeed
                    + "   function " + functionName + "(action, validate) {" + linefeed
                    + "      if (!validate) {" + linefeed
                    + "         document.forms[0].noValidate = true;" + linefeed
                    + "         document.forms[0].action = '' + action;" + linefeed
                    + "         document.forms[0].submit();" + linefeed
                    + "      }" + linefeed
                    + "   }" + linefeed
                    + "</script>" + linefeed;
      }
      return new MvcHtmlString(String.Format("{0}<input type=\"submit\" value=\"{1}\" name=\"button\" onclick=\"{2}('{3}', {4});\" />", javaScript, value, functionName, action, validate ? "true" : "false"));
   }
}

The basic idea is that if the JavaScript function doesn’t exist yet in the view this code adds it. Then it adds one key to the ViewData. If that key is already present this code assumes the JavaScript function has already been added. With this, the JavaScript function can now be removed from the view and all that is needed is this:

  1. MultiSubmitButtonAttribute applied to appropriate controller methods
  2. Use of HtmlHelper.SubmitButton() in view definition

The JavaScript injection is taken care of automatically. Happy coding!

Monday, November 28, 2011

Automapping with Fluent NHibernate: ShouldMap() implementation

When you use the automapping feature of Fluent NHibernate you will very quickly encounter a class called DefaultAutomappingConfiguration. This is the base class for your own automapping configuration class which you want to implement to control certain aspects of the automapping feature.

During startup of your application you have to provide NHibernate with information about how to map your domain classes to the database schema and back. Fluent NHibernate allows doing this automatically. Well, most of the time. There are cases when you want to be a little more specific with regards to those automatically created mappings.

The code you want to execute during startup looks similar to the following:

private static ISessionFactory CreateSessionFactory() {
  var rawConfig = new Configuration();
  rawConfig.SetNamingStrategy(new PostgresNamingStrategy());
  var sessionFactory = Fluently.Configure(rawConfig)
    .Database(PostgreSQLConfiguration.PostgreSQL82
      .ConnectionString(Common.DatabaseConnectionString))
    .Mappings(m => m.AutoMappings
      .Add(AutoMap
        .AssemblyOf<Customer>(new DbMappingConfiguration())
      .Conventions.Add(ForeignKey.EndsWith("Id"))));
   return sessionFactory.BuildSessionFactory();
}

The interesting piece in this case is line 9 where you provide the assembly that contains all your domain classes that you want to map. In this case you only need to provide one such class and Fluent NHibernate will also try to automatically map all other types that it can find in that assembly. Sometimes this is exactly what you want. In other cases you may not want to map all of the classes. Enter the DefaultMappingConfiguration class.

You can implement you own mapping configuration by deriving from DefaultMappingConfiguration. You can override just the aspects that you want to change, everything else is taken care of by the default implementation.

In this post I want to show one way for controlling which classes are mapped. A simplistic approach would be implementing your custom mapping configuration as follows:

public class DbMappingConfiguration 
    : DefaultAutomappingConfiguration {
  public override bool ShouldMap(Type type) {
    return type.Equals(typeof(Customer))
      || type.Equals(typeof(Order))
      || type.Equals(typeof(Address))
      || type.Equals(typeof(Invoice));
  }
}

This works. However as you can imagine this is not very intuitive and you will have to maintain this code as you modify your domain. Each time you add, remove or rename any of your domain classes you will have to update this method (admittedly the renaming is not a problem if you use a refactoring tool).

So let’s think of a better solution. The one I want to present here is based on a marker attribute. The implementation PersistentDomainClassAttribute is very simple:

[AttributeUsage(AttributeTargets.Class, 
                AllowMultiple = false, 
                Inherited = false)]
public class PersistentDomainClassAttribute 
  : Attribute {
}

The usage is fairly simple, too. Here is an example:

[PersistentDomainClass]
public class Customer {
  public virtual Guid Id { get; private set; }
  public virtual string FirstName { get; set; }
  public virtual string LastName { get; set; }
}

Having this in place on all domain classes the custom mapping configuration can now be simplified as follows using a generic implementation:

public class DbMappingConfiguration 
   : DefaultAutomappingConfiguration {
  public override bool ShouldMap(Type type) {
    var attr = type.GetCustomAttributes(
                  typeof(PersistentDomainClassAttribute),
                  true);
    return attr.Length > 0;
  }
}

As a result you now have a solution that lets you choose which domain classes to make persistent. At the same time you no longer have to maintain the ShouldMap() implementation of your custom mapping configuration either.

Sunday, November 27, 2011

Behavior of DirectoryInfo.Delete and Directory.Exists: Directories reappear!?

Please note that the following may be a corner case or an isolated case. If not then something is not quite right with running NUnit based test suites from within Visual Studio 2010 using ReSharper 6. Unfortunately I don’t have proof either way but I still wanted to share my observation just in case you have encountered a similar issue.

A couple of weeks ago I wrote some test code that cleaned up folders after tests were executed. The code looked as follows:

public static void CleanUpFolders(
                    List<DirectoryInfo> directoryInfos) {
   foreach (var directoryInfo in directoryInfos) {
      foreach (var file in directoryInfo.GetFiles("*", 
                            SearchOption.AllDirectories)) {
         file.IsReadOnly = false;
      }
      directoryInfo.Delete(true);
   }

   foreach (var directoryInfo in directoryInfos) {
      Assert.IsFalse(Directory.Exists(directoryInfo.FullName));
   }

   directoryInfos.Clear();
}

For each directoryInfo in the collection the code iterates through all files and sets the read-only attribute to false for each of them. Then the directory is deleted with all its contents.

Then I executed the test suite from within Visual Studio 2010 using ReSharper 6. It turned out that in some cases the assertion in the above code would fail. Despite the directories having been deleted the call to Directory.Exists would return true! So for some reasons the directory was deleted but then it wasn’t. When I reran the tests sometimes this assertion would fail and sometimes it wouldn’t. There were days where it was fine and there were days when the assertion would fail in 90% of the cases.

In addition to this the assertions would only fail on two particular directories but not on any other. I couldn’t identify the commonality between the directories on which the assertion would fail and the directories that were successfully deleted.

Initially I thought that maybe a different process or a different thread would have a handle to the directory. In that case my test would just ask the operation system (Windows 7, 64 bit) to mark the directory as deleted and as soon as the last handle was closed it would be removed. However, the tests would generate names and then create directories with that name. No other thread or process knew about the names. I didn’t have any thread in my system under test that would scan the parent directory thus ‘learning’ about the generated directory names.

To diagnose this issue I tried various things including restarting of Visual Studio and rebooting the workstation. I also tried some of Sysinternals’ tools.

The biggest surprise was an observation that I made when running the tests under the debugger. I set a breakpoint just after the loop that deleted all the directories. At that point Windows Explorer would report those directories as gone. Also when continuing the execution the assertions would not fail. However, once the entire suites was complete, two directories would reappear in Windows Explorer! So despite Directory.Exists stating the Directory to be non-existent it reappeared! This is repeatable.

To take elements out of the equation I got the latest revision of csUnit’s source code and upgraded it to VS2010 and .NET 4.0 (these changes are available at Sourceforge). Then I executed the same test suite without any modification using csUnit. In this case the directories were properly deleted and did not reappear.

Where does that leave me? I don’t know. All I can say is this: My test suite creates a number of directories with generated names. When I execute this suite from within VS2010 and using ReSharper 6, two folders reappear despite DirectoryInfo.Delete() being executed successfully and Directory.Exists() confirming that. However when I execute the same test suite from csUnitRunner, the code behaves as expected and the folders remain deleted. Despite searching for a long time I have not been able to find the reason for this difference in behavior.

The only reasonable conclusion at this stage seem to be that as developers we always need to be suspicious about the tools we use. While they may work in almost all the cases, sometimes they may be the cause for something that doesn’t work.