7

我真的非常想将 URI 作为 RowKey 值存储在 Azure 表存储中。根据文档,RowKeys 不能包含 URI 中常见的字符(/、\、#、?)。

解决方案似乎很简单:只需对 URI 进行编码。但这不起作用。无论出于何种原因,可以插入任何包含序列 %2f(正斜杠的编码值)的值,但即使 '%2f' 不包含任何禁止字符,也不能查询。

好的,那么base64编码怎么样?没有。它偶尔会产生正斜杠字符,这是不允许的。

那么是否有一种方法可以对可以可靠地存储为 Azure Table 中的 RowKey 的字符串(URI)进行编码?最好但不一定是人类可读的东西。

4

5 回答 5

2

使用 base64 编码后用 _ 替换 / 应该可以工作。从编码和解码可能有斜杠的字符串中得到这个建议

于 2013-07-08T18:13:02.163 回答
0

将 URL 中的所有非法行键字符(\、/、?)替换为 URLS 中的非法字符(例如 <、>、%)

于 2013-02-14T09:17:32.737 回答
0

离题但相关:我正在动态创建表格,并且如果您需要它,我的代码可以帮助您,尽管表格和 PK/RK 的规则完全不同。“^[A-Za-z][A-Za-z0-9]{2,62}$”。

也许您可以使用它来激发您自己的解决方案

解码一个字符串

        string edit1 = host
            .Replace("qqu", "_")
            .Replace("qqh", "-")
            .Replace("qqp", ".")

            // NOTE: qqn is reserved leading sequence

            .Replace("qqt", "qqu")
            .Replace("qqo", "qqp")
            .Replace("qqg", "qqh")
            ;

        if (edit1.StartsWith("qqn"))
        {
            edit1 = edit1.Substring(3, edit1.Length);
        }
        if (edit1.StartsWith("qq"))
        {
            edit1 = edit1.Substring(2, edit1.Length);
        }

编码字符串的方法

            string edit1 = this.originalName.ToLower().Trim()
                .Replace("qqu", "qqt")
                .Replace("qqp", "qqo")
                .Replace("qqh", "qqg")

                // NOTE: qqn is reserved leading sequence

                .Replace("_", "qqu")
                .Replace("-", "qqh")
                .Replace(".", "qqp");

            string test = "qq";
            if (edit1.StartsWith(test))
                return test + "n" + edit1;

            test = "0";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "1";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "2";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "3";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "4";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "5";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "6";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "7";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "8";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "9";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "0";
            if (edit1.StartsWith(test))
                return "qq" + edit1;
于 2012-09-22T00:22:24.760 回答
0

几种可能性:

  1. 使用某些特定编码(例如,UTF-8)转换字节,然后将字节编码为十六进制。用它作为关键。但是,有些 URI 可能会很长,而 key 会更长,因此您可能会遇到 RowKey 的最大长度。
  2. 散列 URI(例如,使用 MD5)。十六进制编码这些字节并将它们用作密钥。请注意,有可能发生冲突,但您的 PartitionKey 可能会消除这种可能性。由于哈希是恒定长度,因此最大 RowKey 长度不应该有问题。

我敢肯定还有其他想法,我很想听听他们的意见。

于 2012-09-21T22:23:19.573 回答
0
public static string Encode(string rawText)
    {
        return Regex.Replace(rawText, @"[/\?\:@\&=\+,\$]", delegate(Match m)
        {
            switch (m.Value)
            {
                case "/": return "{#sl}";
                case "?": return "{#qm}";
                case ":": return "{#cl}";
                case "@": return "{#at}";
                case "&": return "{#am}";
                case "=": return "{#eq}";
                case "+": return "{#pl}";
                case ",": return "{#cm}";
                case "$": return "{#dl}";

                default: return m.Value;
            }
        });
    }

public static string Decode(string encodedText)
    {
        return Regex.Replace(encodedText, @"\{#[a-z]{2}\}", delegate(Match m)
        {
            switch (m.Value)
            {
                case "{#sl}": return "/";
                case "{#qm}": return "?";
                case "{#cl}": return ":";
                case "{#at}": return "@";
                case "{#am}": return "&";
                case "{#eq}": return "=";
                case "{#pl}": return "+";
                case "{#cm}": return ",";
                case "{#dl}": return "$";

                default: return m.Value;
            }
        });
    }
于 2015-08-08T00:38:04.943 回答