InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Exchange WebServices Bug with Lineendings

When you fetch the body of a mail via Exchange WebServices you might have noticed the fact that the body of the mail has its line endings, which are normally represented by a CRLF (“\r\n” in C#) replaced with a simple LF (“\n”). For the text and HTML body, this is the expected behavior. But Exchange also enforces this behavior on custom properties, which was not intended.

Below is a small program that demonstrates the problem. It creates a new item in the drafts folder of the current users mailbox and then reads the content back. You’ll notice the missing \r characters when you examine the propertyValue property.

   1: using System;
   2: using System.Linq;
   3: using System.Net;
   4: using Microsoft.Exchange.WebServices.Data;
   5:  
   6: namespace TestApplication
   7: {
   8:     internal class Program
   9:     {
  10:         private static void Main()
  11:         {
  12:             ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
  13:             var service = new ExchangeService(ExchangeVersion.Exchange2007_SP1)
  14:                           {
  15:                           Url = new Uri("https://w2k3x64/ews/exchange.asmx"),
  16:                           UseDefaultCredentials = true,
  17:                           };
  18:             Folder folder = Folder.Bind(service, WellKnownFolderName.Drafts);
  19:             var item = new PostItem(service) {Subject = "test", Body = "Line1\r\nLine2"};
  20:  
  21:             var definition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "TestProperty",
  22:                                                             MapiPropertyType.String);
  23:             item.ExtendedProperties.Add(definition, "Line1\r\nLine2");
  24:             item.Save(folder.Id);
  25:  
  26:             ItemId id = item.Id;
  27:             item = PostItem.Bind(service, id, new PropertySet(BasePropertySet.FirstClassProperties, definition));
  28:             string propertyValue = (from property in item.ExtendedProperties 
  29:                                     where property.PropertyDefinition == definition 
  30:                                     select property.Value).First();
  31:  
  32:             Console.Out.WriteLine("item.Body = {0}", item.Body);
  33:             Console.Out.WriteLine("propertyValue = {0}", propertyValue);
  34:  
  35:             Console.ReadLine();
  36:         }
  37:     }
  38: }

So, if you are struggling with this ‘anomaly’, you need to open a case with the Microsoft products support (PSS) to get a fix.


Posted by Henning Krause on Tuesday, August 25, 2009 9:04 PM, last modified on Tuesday, August 25, 2009 9:04 PM
Permalink | Post RSSRSS comment feed

X509Certificate2 Constructor creates two empty files in the temporary files directory [Update]

2009-04-18: Microsoft has indeed a knowledgebase article on this topic and there is a hotfix availbe.

The .NET Framework has a nice class called X509Certificate2 that simplifies the handling of X.509 certificates. Specifically, it has a constructor that takes a byte array that allows a developer to load a certificate from an arbitrary storage like a database. The class uses some Win32 to parse the byte array, and one of the used functions contain a bug: During the load process, two empty temporary files are created in the temporary files directory of the user running the code. Unfortunately, these files are never cleaned up, so they accumulate over time. What’s worse, they seem to be created by the GetTempFilename function. This function creates an empty file in a specific directory with a name guaranteed to be unique. These files have a prefix (up to three letters) and a number. The number is generated by the GetTempFilename function in a sequential manner. Since the two files are never deleted by the Win32 function, the call to GetTempFilename takes longer and longer. In my case, I had over 65.000 files in the temporary files directory and the X509Certificate2 constructor took several seconds to complete.

Microsoft knows about this bug, but they don’t seem eager to fix it. More details can be found on this connect link: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=284551.

Since there will be no fix in the near future, you can use this workaround: Instead of loading the certificate from a byte array, dump it to a file and read it from there. The following snippet demonstrates this workaround:

   1: public static X509Certificate2 LoadCertificate(byte[] buffer)
   2: {
   3:     if (buffer == null) throw new ArgumentNullException("buffer");
   4:  
   5:     string filename = Path.GetTempFileName();
   6:     try
   7:     {
   8:         File.WriteAllBytes(filename, buffer);
   9:         return new X509Certificate2(filename);
  10:     }
  11:     finally
  12:     {
  13:         try
  14:         {
  15:             File.Delete(filename);
  16:         }
  17:         catch
  18:         {
  19:             // This is ok - the file is in the temporary files directory. No harm done.
  20:         }
  21:     }
  22: }

Hotfix

The knowledgebase article 931908 deals with this problem and offers a hotfix. The hot fix can be requested directly from the article.


Posted by Henning Krause on Sunday, March 29, 2009 3:13 PM, last modified on Saturday, April 18, 2009 11:02 PM
Permalink | Post RSSRSS comment feed