开发者

Encoding and decoding a string that may have slashes in it

I have strings like this:

RowKey = "Local (Automatic/Manual) Tests",

When I try to store in Windows Azure then this fails as I assume it does not accept the "/" as part of the row key.

Is there a simple way that I can encode the value before putting into RowK开发者_如何学JAVAey?

Also once the data is in the table I get it out with the following:

var Stores = storeTable.GetAll(u => u.PartitionKey == "ABC");

Is there a simple way that I can get out the value of RowKey and decode it?


One possible way for handling is this by converting the PartitionKey and RowKey values in Base64 encoded string and save it. Later when you retrieve the values, you just decode it. In fact I have had this issue some days back in our tool and Base64 encoding was suggested to me on MSDN forums: http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/a20cd3ce-20cb-4273-a1f2-b92a354bd868. But again it is not fool proof.


I'm not familiar with Azure, so I don't know if there is an existing API for that. But it's not hard to code:

encode:

const string escapeChar='|';
RowKey.Replace(escapeChar,escapeChar+escapeChar).Replace("/",escapeChar+"S");

decode:

StringBuilder sb=new StringBuilder(s.Length);
bool escape=false;
foreach(char c in s)
{
  if(escape)
  {
    if(c=='S')
      sb.Append('/');
    else if(c==escapeChar)
      sb.Append(escapeChar);
    else
      throw new ArgumentException("Invalid escape sequence "+escapeChar+c);
  }
  else if(c!=escapeChar)
  {
    sb.Append(c);
    escape=false;
  }
  else
    escape=true;
  return sb.ToString();


When a string is Base64 encoded, the only character that is invalid in an Azure Table Storage key column is the forward slash ('/'). To address this, simply replace the forward slash character with another character that is both (1) valid in an Azure Table Storage key column and (2) not a Base64 character. The most common example I have found (which is cited in other answers) is to replace the forward slash ('/') with the underscore ('_').

private static String EncodeToKey(String originalKey)
{
    var keyBytes = System.Text.Encoding.UTF8.GetBytes(originalKey);
    var base64 = System.Convert.ToBase64String(keyBytes);
    return base64.Replace('/','_');
}

When decoding, simply undo the replaced character (first!) and then Base64 decode the resulting string. That's all there is to it.

private static String DecodeFromKey(String encodedKey)
{
    var base64 = encodedKey.Replace('_', '/');
    byte[] bytes = System.Convert.FromBase64String(base64);
    return System.Text.Encoding.UTF8.GetString(bytes);
}

Some people have suggested that other Base64 characters also need encoding. According to the Azure Table Storage docs this is not the case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜