Validating partition and row keys in Azure Table Storage
Microsoft Azure Table storage is a very flexible No-Sql store for structured data. Each entity in the table is uniquely identified by a partition key and a row key.
A good choice of these is beyond the scope of this post. However, it can be useful to check that entity you want to add to the table has valid partition and row keys. Here's a simple class that encapsulates those rules:
/// <summary>
/// Encapsulates knowledge about valid values for keys in Microsoft Azure table storage.
/// </summary>
/// <remarks>
/// Rules are found here http://msdn.microsoft.com/library/azure/dd179338.aspx
/// </remarks>
internal static class KeyValidator
{
/// <summary>
/// Determines whether the specified key is valid.
/// </summary>
/// <param name="keyValue">The key.</param>
/// <param name="errors">Any errors in the value supplied.</param>
/// <returns><c>true</c> if the key value is valid; otherwise <c>false</c></returns>
internal static bool IsKeyValid(string keyValue, out ICollection<string> errors)
{
errors = new List<string>();
if (!ValidateLength(keyValue))
{
errors.Add("Maximum length exceeded. Key should be less than 1kb.");
}
if (ContainsInvalidCharacter(keyValue))
{
errors.Add("Key contains illegal characters");
}
return errors.Count == 0;
}
/// <summary>
/// Determines whether the specified key is valid.
/// </summary>
/// <param name="keyValue">The key.</param>
/// <returns><c>true</c> if the key value is valid; otherwise <c>false</c></returns>
internal static bool IsKeyValid(string keyValue)
{
return
ValidateLength(keyValue) && ContainsInvalidCharacter(keyValue);
}
private static bool ValidateLength(string key)
{
// 1Kb upper limit on key length. String.Length == number of Char instances
// NOT number of unicode chars.
return key.Length < 512;
}
private static bool ContainsInvalidCharacter(string key)
{
// Rules specify 2 ranges that characters aren't allowed to be from
// as well as a list of 4 characters.
const char controlLower1 = '\u0000';
const char controlUpper1 = '\u001F';
const char controlLower2 = '\u007F';
const char controlUpper2 = '\u009F';
var disallowedChars = new[] {'/', '\\', '#', '?'};
return key.Any(c => disallowedChars.Contains(c) ||
(c > controlLower1 && c < controlUpper1) ||
(c > controlLower2 && c < controlUpper2));
}
}
Used as simply as:
// Care about specific errors
List<String> errors;
KeyValidator.IsKeyValid("some-value", out errors);
// Or, just need to know if allowable
KeyValidator.IsKeyValid("some-other-value");
Comments
Post a Comment