Monthly Archives: May 2010

WCF REST: generate correct Content-Length header for HEAD request

The point of a HEAD request is to return a Content-Length header, but with an empty body. The WCF transport stack has the annoying ‘feature’ that it ‘corrects’ the Content-Length header based on the stream that is returned. With the aid of Carlos Figueira’s MyLengthOnlyStream i was able to workaround that ‘feature’ :) (I know, i know, a good old HttpHandler is so much easier to implement!)

Support both GET and HEAD requests on the same method with WCF REST

A while ago i had to modify an existing WCF REST service which was being consumed by BITS. Apparently the implementation has changed in Windows7 in such a way that the BITS client first makes a HEAD request to discover the file size.

The following attempts did not work:

// A method can not have both WebGet and WebInvoke attributes
[OperationContract]
[WebGet]
[WebInvoke(Method="HEAD")]
public Stream Download(string token) { }


// A method can not have multiple WebInvoke attributes
[OperationContract]
[WebInvoke(Method="GET")]
[WebInvoke("HEAD")]
public Stream Download(string token) { }

The trick is to use * as Method and handle the method related logic in your code:

[OperationContract]
[WebInvoke(Method="*")]
public Stream Download(string token)
{
 var method = WebOperationContext.Current.IncomingRequest.Method;
 if (method == "HEAD") return ProcessHead();
 if (method == "GET") return ProcessGet();
 throw new ArgumentException(method + " is not supported.");
}

Microsoft SQL Server 2008 Internals

Around new year i found out that i would be working with SQL Server 2008 so i needed a crash course. Microsoft SQL Server 2008 Internals is really not intended to be that, but it does cover the basics and then dives (way too) deep in detail. Although i stopped reading halfway the dives i found the book very interesting!

Windows Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition

Given the fact that i have been developing software for MS-Windows the last couple of years i found it important to learn a bit more about the internals of the operating systems on which my applications run so i ordered a copy of Windows Internals: Including Windows Server 2008 and Windows Vista, Fifth Edition back in september and learned quite a bit from the chapters that i found interesting: security, authorization, networking and analyzing crashes. I skimmed through the chapters on memory management, scheduling and file systems because they reminded me too much of Tanenbaum’s excellent Modern Operating Systems.

97 Things Every Project Manager Should Know: Collective Wisdom from the Experts

Lately i felt the need to work on my management skills so apart from practicing each day i decided to search for some inspiration in 97 Things Every Project Manager Should Know: Collective Wisdom from the Experts. All i can say is that it’s yet another book in the series that is worth reading.

Enumerating SpecialFolders

Environment.SpecialFolder is a value-type that i always seem to forget about. Let’s try to do something about that by posting about it here ;)

foreach (var name in Enum.GetNames(typeof(Environment.SpecialFolder)))
{
 var specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), name);
 Console.WriteLine("{0,25} => {1}", name, Environment.GetFolderPath(specialFolder));
}


Desktop C:\Users\timvw\Desktop
Programs C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Personal C:\Users\timvw\Documents
MyDocuments C:\Users\timvw\Documents
Favorites C:\Users\timvw\Favorites
Startup C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
Recent C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Recent
SendTo C:\Users\timvw\AppData\Roaming\Microsoft\Windows\SendTo
StartMenu C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu
MyMusic C:\Users\timvw\Music
DesktopDirectory C:\Users\timvw\Desktop
MyComputer
Templates C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Templates
ApplicationData C:\Users\timvw\AppData\Roaming
LocalApplicationData C:\Users\timvw\AppData\Local
InternetCache C:\Users\timvw\AppData\Local\Microsoft\Windows\Temporary Internet Files
Cookies C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Cookies
History C:\Users\timvw\AppData\Local\Microsoft\Windows\History
CommonApplicationData C:\ProgramData
System C:\Windows\system32
ProgramFiles C:\Program Files
MyPictures C:\Users\timvw\Pictures
CommonProgramFiles C:\Program Files\Common Files

Get root directory for IsolatedStorageFiles

Sometimes you want to know the absolute path of a file that is persisted with IsolatedStorageFile. Apparently there is an internal property RootDirectory which contains this information:

public static class IsolatedStorageFileExtensions
{
 public static string GetRootDirectory(this IsolatedStorageFile isf)
 {
  var property = isf.GetType().GetProperty("RootDirectory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty);
  return (string)property.GetValue(isf, null);
 }
}

Here is a real world example of using SharpBITS.NET to download a file to IsolatedStorage:

class Program
{
 static void Main()
 {
  var mgr = new BitsManager();
  mgr.OnJobError += mgr_OnJobError;
  mgr.OnJobTransferred += mgr_OnJobTransferred;

  var job = mgr.CreateJob("job@" + DateTime.Now, JobType.Download);
  var src = @"http://localhost/";
  var dst = Path.Combine(GetIsfRoot(), "test.html");
  job.AddFile(src,dst);
  job.Resume();

  Console.WriteLine("running...");
  Console.ReadKey();
 }

 static void mgr_OnJobTransferred(object sender, NotificationEventArgs e)
 {
   e.Job.Complete();
   Console.WriteLine("completed: " + e.Job.DisplayName);
  }

 static void mgr_OnJobError(object sender, ErrorNotificationEventArgs e)
 {
  Console.WriteLine("error: " + e.Error.Description);
 }

 static string GetIsfRoot()
 {
  using (var f = IsolatedStorageFile.GetUserStoreForAssembly())
  {
   return f.GetRootDirectory();
  }
 }
}