Make sure to use Unix path separator while working with AWS .Net SDK

Ran into the following signature mismatch exception while trying to upload a file into a folder on using using AWS .Net  SDK.

“Amazon.S3.AmazonS3Exception : The request signature we calculated does not match the signature you provided. Check your key and signing method.”

Uploading files in the root of the bucket worked fine, but, the signature calculated by the SDK didn’t match the server calculated signature while trying to upload to a folder.  The problem turned out to be the path separator, AWS include object key while calculating request signature, but, the server is using ‘/’ as path separator, while the SDK uses whatever you set. Since most the .Net functions use ‘\’ to separate paths make sure to replace the separator while creating the request.

image

Using Unix style path separator fixed the problem.

image

Tip: Delete Unversioned Items

Having multiple branches of a project or multiple projects checked out makes it easier to quickly switch between them. But, one disadvantage of keeping multiple working copies checkout is that the temporary obj and binaries hog a lot of hard disk space, this becomes a major problem if you are using a SSD and don’t have a ton of free space.

Tortoise SVN can help you remove all the temporary files and reclaim that precious disk space, just right click on the working copy while holding the shift key down and choose “delete unversioned items”, this will display all the unversioned items and allow you to delete them.

image

Just make sure to uncheck “Use recycle bin”

image

SQLite.Net Custom Functions not getting registered after upgrading to .Net 4.5

SQLite’s ADO.NET adapter System.Data.SQLite supports for user defined SQL functions. New functions are implemented by deriving a class from SQLiteFunction class and applying SQLiteFunctionAttribute to it. At run time SQLite.Net reflects on all the assemblies loaded in the AppDoamin to automatically register all the use-defined SQL functions.

We have a few user-defined functions which we have been using for a long time without any problem. But, after installing .Net 4.5 on my system none of the user-defined function work. Somehow SQLite was not able to find the custom functions after the 4.5 upgrade. It turned out that in .Net 4.5 CLR Microsoft tweaked the order in which static constructors get called.

Here is the SQLiteFunction static constructor where all the user defined functions are registered.image

In order to minimize the number of assemblies that need to be examined, the code only goes through types which reference System.Data.SQLite.dll. That’s a good idea, but, it does it in a weird way, it compares the referenced assembly name with the name of the assembly that called this method (GetCallingAssembly) , rather than the name of the assembly that contains this code (GetExecutingAssembly).

This never caused any problem in .Net 4.0 and older version because SQLiteFunction’s static constructors always got called from within its instance constructor.

image

But, in .Net 4.5, CLR calls the static constructor before the instance constructor.

image

And in this case the calling assembly is no longer the SQLite assembly itself, and therefore the SQLiteFunction’s static constructors skips all the user-defined functions.

Interestingly I was only able to reproduce the problem in an asp.net web application, somehow in console app static constructor gets called from instance constructor even in .Net 4.5.

The sample app I used to test this is available in GitHub here.

Fixing the problem should be easy enough, either replace GetCallingAssembly with GetExecutingAssembly and recompile the SQLite.dll or just manually register all the user defined functions using SQLiteFunction’s static RegisterFunction method.

UPDATE: SQLite.Net maintainers were quick to address this, mistachkin fixed it on the same day. Here is the url for sqlite.net ticket: http://system.data.sqlite.org/index.html/tktview?name=4e49a58c4c. Thanks mistachkin.

.Net Path Class Usage

ChangeExtension Changes the extension of a path string.

(C:\mydir\myfile.com.extension, .old)=> C:\mydir\myfile.com.old
(C:\mydir\myfile.com.extension, )=> C:\mydir\myfile.com.
(C:\mydir\, .old)=> C:\mydir\.old

Combine(String[]) Combines an array of strings into a path.

new[]{@"d:\archives", "2001", "media"} => d:\archives\2001\media

new[]{@"d:\archives", "2001", "\media"} => media (details)

Public methodStatic memberSupported by the XNA Framework
GetDirectoryName Returns the directory information for the specified path string.

C:\MyDir\MySubDir\myfile.ext => C:\MyDir\MySubDir

C:\ =>

Public methodStatic memberSupported by the XNA FrameworkGetExtension Returns the extension of the specified path string.

C:\mydir.old\myfile.ext => .ext

C:\mydir.old\ =>

Public methodStatic memberSupported by the XNA Framework
GetFileName Returns the file name and extension of the specified path string.

C:\mydir\myfile.ext => myfile.ext

C:\nydir =>

Public methodStatic memberSupported by the XNA Framework
GetFileNameWithoutExtension Returns the file name of the specified path string without the extension.

C:\mydir\myfile.ext => myfile

C:\mydir\ =>

Public methodStatic memberSupported by the XNA Framework
GetFullPath Returns the absolute path for the specified path string.

mydir => c:\temp\Demo\mydir [currentdir\mydir]

\mydir => c:\mydir

Public methodStatic memberGetInvalidFileNameChars Gets an array containing the characters that are not allowed in file names.Supported by the XNA Framework

Windows 7:

(",  0022) (<,  003C) (>,  003E) (|,  007C) (□,  0000) (□,  0001) (□,  0002) (□,  0003) (□,  0004) (□,  0005) (□,  0006) (□,  0007) (□,  0008) 0009 000A 000B 000C 000D (□,  000E) (□,  000F) (□,  0010) (□,  0011) (□,  0012) (□,  0013) (□,  0014) (□,  0015) (□,  0016) (□,  0017) (□,  0018) (□,  0019) (□,  001A) (□,  001B) (□,  001C) (□,  001D) (□,  001E) (□,  001F) (:,  003A) (*,  002A) (?,  003F) (\,  005C) (/,  002F)

GetInvalidPathChars Gets an array containing the characters that are not allowed in path names.

Windows 7:

Windows 7:

(",  0022) (<,  003C) (>,  003E) (|,  007C) (□,  0000) (□,  0001) (□,  0002) (□,  0003) (□,  0004) (□,  0005) (□,  0006) (□,  0007) (□,  0008) 0009 000A 000B 000C 000D (□,  000E) (□,  000F) (□,  0010) (□,  0011) (□,  0012) (□,  0013) (□,  0014) (□,  0015) (□,  0016) (□,  0017) (□,  0018) (□,  0019) (□,  001A) (□,  001B) (□,  001C) (□,  001D) (□,  001E) (□,  001F)

Public methodStatic memberSupported by the XNA Framework
GetPathRoot Gets the root directory information of the specified path.

\mydir\ => \

myfile.ext =>

c:\mydir\myfile.ext => c:\

Public methodStatic member
GetRandomFileName Returns a random folder name or file name

w143kxnu.idj

Public methodStatic member
GetTempFileName Creates a uniquely named, zero-byte temporary file on disk and returns the full path of that file.

This method creates a temporary file with a .TMP file extension. The temporary file is created within the user’s temporary folder, which is the path returned by the GetTempPath method.

Static member
GetTempPath Returns the path of the current user’s temporary folder.

This method checks for the existence of environment variables in the following order and uses the first path found:

  1. The path specified by the TMP environment variable.
  2. The path specified by the TEMP environment variable.
  3. The path specified by the USERPROFILE environment variable.
  4. The Windows directory.

Public methodStatic memberHasExtension Determines whether a path includes a file name extension.

myfile.ext => True

mydir\myfile => False

C:\myDir.ext\ => False

Public methodStatic memberSupported by the XNA Framework
IsPathRooted Gets a value indicating whether the specified path string contains a root.

Simplify Unit testing with Beyond Compare

Consider the following NullValueHandlingBlogPost unit test from Json.Net.

image

Assume you are maintaining this test and once fine Friday evening at 6pm (they always break @ 6pm) you get an alert from build system that NullValueHandlingBlogPost failed.

image

Description don’t match, but, that’s not the only difference, ReleaseCounteries is also different, so once you fix Description and run the unit test again you will find out about ReleaseCounteries and you can go ahead and fix that too. This was a trivial case, spotting similar differences in a complex xml is a lot more headache.

What if, rather than NUnit output strings, you get the following BeyondCompare diff screen whenever the expected and actual string don’t match.

image

Now isn’t this so much better, here I am launching launch Beyond Comapre if the expected and actual text does not match in the unit test, like this:

image

In a single glance you can spot all the differences and get a better understanding of the bug causing the unit test to fail. This saved me a good couple of hours trying to fix a unit test involving large xml configuration file. You can use any diff tool that you like, here @ B-Line Medical we are BeyondCompare fan, so I used that.  I added a couple of more methods to compare files and objects as well.

image

Checkout the BeyondCompare class’s source here.