Enabling SQL FILESTREAM on your machine

I tried to play with FILESTREAM on my laptop. I didn’t enable the option at install time, so I went to the SQL Server Configuration Manager to enable the setting:

Enable FILESTREAM for Transact-SQL access

However when checking the first 2 checkboxes I was met with the following wonderful error:

There was an unknown error appyling the FILESTREAM settings. Check the parameters are valid.

There was an unknown error appyling the FILESTREAM settings. Check the parameters are valid.

This didn’t give me any search results, out of options I reinstalled SQL Server. When trying to enable FILESTREAM through the installer I was met with the following error:

Error 2114 validating the Windows share name MSSQLSERVER.

Good, searching on this resulted in the following blog (only 1 result!!!):

http://nfrelat.wordpress.com/2008/12/30/sql-2008-installation-strange-issue/

BAM, you need the Server Service running, which by default, is off on Windows 7.

Server Service Properties

Set it to automatic and start the service (or reboot machine).

And you’re good to go Open-mouthed smile

On a side note, it seems that the Server Service only needs to run when enabling the FILESTREAM, afterwards it seems to work fine with the thing set to Disabled… Don’t know why.

Have a good one,

-Kristof

Unless you have a VERY good reason, rethrow your exception.

I see it a lot, people write a function, they catch a possible exception and throw one of their own OmgSomethingHorribleHappenedException();

Check this simplefied example:

private static void Main()
{
	try
	{
		var result = (new Api()).Find("foo");
 
		Process(result);
	}
	catch (Exception e)
	{
		Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
		Console.Read();
	}
}

And the Api.Find(string toFind) method:

namespace ExceptionRethrow
{
	using System;
	using System.Linq;
 
	public class Api
	{
		public string Find(string toFind)
		{
			try
			{
				// force a InvalidOperationException
				return (new string[] { }).Single(e => e == toFind);
			}
			catch (InvalidOperationException e)
			{
				Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
				throw e;
			}
		}
	}
 
	public class Logger
	{
		public static void Log(string message)
		{
			Console.WriteLine(message);
		}
	}
}

As you can see in the Api.Find method we catch the exception from the Single call, log the error (to notify the developers or something, …) and throw the exception again.

However when we look at the call stack in the Main method we see this:

e.StackTrace

Odd, what’s line 19 in Api.cs? Right, throw e. Useful! NOT!

So you need to replace the throw e by throw.

//...
catch (InvalidOperationException e)
{
	Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
	throw; // removed the 'e'
}
//...

Then the result will look like this:

e.StackTrace

Now we already know little more about the cause. However to improve we need to catch the error, and throw it again by passing in the current exception as inner exception:

//...
catch (InvalidOperationException e)
{
	Logger.Log(string.Format("Tried to look for element {0}, not found", toFind));
 
	throw new InvalidOperationException(e.Message, e);
}
//...

So let’s debug again:

e.StackTrace

Again we only see the lines where the exception was thrown last, however when we investigate the InnerException’s stacktrace we get way more info:

e.InnerException.StackTrace

Now that’s an exception that’s useful to debug Smile

We can leverage this knowledge in multiple ways, one of which is shielding exceptions, making sure none go through to the client. For example when your service broker detects an error, it clears the InnerException field, thus removing any business knowledge from the exception.

When in debug mode you can want to send over those exceptions to improve the finding of bugs Smile

You can find the complete example on GitHub.

Have a good one,

-Kristof

Deserializing xml: Data at the root level is invalid. Line 1, position 1

A couple of days ago a colleague of mine encountered a problem where he had some objects that define a configuration needed to be stored in the database.

He would serialize the data with the following code:

public static class XmlSerializerHelper
{
    public static string SerializeXml<TObject>(this TObject objectToSerialize)
    {
        using (var memoryStream = new MemoryStream())
        {
            var xmlSerializer = new XmlSerializer(typeof (TObject));

            var xmlnsEmpty = new XmlSerializerNamespaces(new[]
                {
                    new XmlQualifiedName(string.Empty, string.Empty),
                });

            var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

            xmlSerializer.Serialize(xmlTextWriter, objectToSerialize, xmlnsEmpty);

            return Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int) memoryStream.Length);
        }
    }
}

And we would read deserialize the string with these lines:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Entity));
StringReader stringReader = new StringReader(result /* result is the value from the database */);
Entity deserializedEntity = (Entity)xmlSerializer.Deserialize(stringReader);

When the string then was read from the database we got an error:

{"Data at the root level is invalid. Line 1, position 1."}
{“Data at the root level is invalid. Line 1, position 1.”}

Let’s check why.

I think the exception is in the first 2 characters of the xml:

What's the string?

Nothing weird there… However, let’s look at the characters themselves:

char at index 0

What the? What’s that thing there at [0]? Who put it there?

Well, according to some web documentation it’s the ZERO WIDTH NO-BREAK SPACE (what’s with the screaming anyway…), also known as the BOM!

So what is the BOM? Wikipedia does a better explanation than me. The only thing you need to know is that it is optional.

So where is it coming from? And why is this an issue?

Let’s investigate our serializer helper, we run the code again, but a breakpoint in the method that actually serializes the entity, and investigate the memoryStream:

investigating the stream

As we can see, after carefully reading the Wikipedia page, these first 3 chars are actually the BOM. So the issue is not our reader, it’s our writer.

Let’s get back to the question: why is this an issue? Why can’t our reader interpret this as just a UTF-8 string, and just parse it, why do we manually have to do a TrimStart()?

It seems that the StringReader used in our code just passes through the string as a stream to our deserializer, without caring whether the string starts with or without a BOM. So we can’t do anything there except for calling the TrimStart() method as mentioned above.

So since we control both sides, let’s do it less nasty, the documentation mentions that the BOM is not required, and our reader doesn’t play nice with it. We’re not going to save it at all then Smile.

Let’s check the XmlTextWriter constructor: it accepts 2 parameters, a stream and an encoding. So what’s with this encoding? Apparently if we use the Encoding.UTF8 it emits the BOM. We can avoid this by using new UTF8Encoding(false) to prevent the BOM from being emitted.

Another way, which I find cleaner is this one, using a StringWriter which automatically infers the correct encoding.:

public static class XmlSerializerHelper
{
	public static string SerializeXml<TObject>(this TObject objectToSerialize)
	{
		XmlSerializer xmlSerializer = new XmlSerializer(typeof (TObject));
 
		XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces(new[]
			{
				new XmlQualifiedName(string.Empty, string.Empty),
			});
 
		StringWriter stringWriter = new StringWriter();
 
		xmlSerializer.Serialize(stringWriter, objectToSerialize, xmlnsEmpty);
 
		return stringWriter.ToString();
	}
}

This doesn’t involve any encoding being manipulated / used on our side, so it uses a bit more magic, but it’s way more straightforward. Please add your experience to the comments Smile

You can find the full code on GitHub here!

Have a good one,

-Kristof

Check if your LinkedIn password appears in the leaked file.

  1. Get the file from the internet.
  2. Change the line that points to the file.
  3. Run the app, type your password and be happy or sad.
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Security.Cryptography;
using System.Text;
 
namespace LinkedInFileSearcher
{
	internal static class Program
	{
		private const string PathToLinkedInFile = @"c:\combo_not.txt";
 
		private static void Main()
		{
			ConsoleKeyInfo consoleKeyInfo;
			Console.Write("Please enter password, keypresses won't be visible: ");
 
 
			var passwordStringBuilder = new StringBuilder();
 
			do
			{
				// hide keypresses
				consoleKeyInfo = Console.ReadKey(true);
 
				if (consoleKeyInfo.Key == ConsoleKey.Backspace)
				{
					if (passwordStringBuilder.Length <= 0)
					{
						continue;
					}
 
					passwordStringBuilder.Remove(passwordStringBuilder.Length - 1, 1);
				}
 
				passwordStringBuilder.Append(consoleKeyInfo.KeyChar);
			}
			while (consoleKeyInfo.Key != ConsoleKey.Enter);
 
			Console.WriteLine();
			Console.WriteLine();
			Console.WriteLine();
 
			string pass = passwordStringBuilder.ToString().Trim();
 
			SHA1 sha1 = SHA1.Create();
			byte[] passwordBytes = Encoding.UTF8.GetBytes(pass);
			byte[] computedHash = sha1.ComputeHash(passwordBytes);
 
			var stringBuilder = new StringBuilder();
 
			// Loop through each byte of the hashed data 
			// and format each one as a hexadecimal string.
			for (int i = 0; i < computedHash.Length; i++)
			{
				stringBuilder.Append(computedHash[i].ToString("x2"));
			}
 
			string hashedPasswordAsString = stringBuilder.ToString();
 
			string substringOfPassword = hashedPasswordAsString.Substring(5);
 
			Console.WriteLine("Searching for" + Environment.NewLine + "{0} or " + Environment.NewLine + "{1} in the database", hashedPasswordAsString, substringOfPassword);
 
			// using a memory mapped file to not load everything in memory all at once. 
			using (MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(PathToLinkedInFile))
			{
				Stream memoryMappedViewStream = memoryMappedFile.CreateViewStream();
 
				using (var sr = new StreamReader(memoryMappedViewStream, Encoding.UTF8))
				{
					while (!sr.EndOfStream)
					{
						String line = sr.ReadLine();
						if (null == line || !line.EndsWith(substringOfPassword))
						{
							continue;
						}
 
						if (line == hashedPasswordAsString)
						{
							Console.WriteLine("Complete SHA-1 match found: " + line);
						}
						else
						{
							Console.WriteLine("Partial SHA-1 match found: " + line);
						}
					}
				}
			}
			Console.WriteLine();
			Console.WriteLine();
			Console.WriteLine("Done... if no matches are found you should be happy.");
			Console.ReadLine();
		}
	}
}

You can find the full code here. Please fork and update!