【问题标题】:Converting a Byte[] from a Session back to a List<String> in c#在 c# 中将 Byte[] 从 Session 转换回 List<String>
【发布时间】:2021-04-12 10:18:50
【问题描述】:

我尝试通过将列表转换为 Byte[] 来将列表保存在会话中。但是当我尝试将其转换回列表时,我只会得到一些随机数。这是我可以保存包含语言的列表的唯一方法。

在我转换并保存在会话中的代码下方

   private void AllowedLanguages(Userdata User)
        {
            List<string> languages = new List<string>();            

            if (User.Deutsch == true) { languages.Add("Deutsch"); }
            if (User.Englisch == true) { languages.Add("Englisch"); }
            if (User.Französisch == true) { languages.Add("Französisch"); }
            if (User.Italienisch == true) { languages.Add("Italienisch"); }
            if (User.Japanisch == true) { languages.Add("Japanisch"); }
            if (User.Mandarin == true) { languages.Add("Mandarin"); }
            if (User.Polnisch == true) { languages.Add("Polnisch"); }
            if (User.Portugiesisch == true) { languages.Add("Portugiesisch"); }
            if (User.Spanisch == true) { languages.Add("Spanisch"); }

            byte[] LanguagesInBytes = languages
             .SelectMany(s => System.Text.Encoding.ASCII.GetBytes(s))
             .ToArray();

            HttpContext.Session.Set("AllowedLanguages", LanguagesInBytes);
        }

这是我尝试将其返回到 Arraylist 或任何其他类型的带有字符串的列表的代码

            var LanguagesByte = HttpContext.Session.Get("AllowedLanguages");

            for (int i = 0; i < LanguagesByte.Length; i++)
            {
                String str = new String(LanguagesByte[i].ToString());
                Languages.Add(str);
            }

在我将其转换回以在页面上显示后,列表应该看起来像以前一样。这甚至是正确的方法还是我完全错了?

【问题讨论】:

  • 不,您将不得不对列表进行序列化和反序列化。旁白:为什么用户不只是将列表作为属性?
  • 我对上面的列表方式进行了序列化,用户是来自 SQL 数据库的对象
  • 应该对数据库中的表进行规范化,否则您需要为每种新语言添加一列。您的反序列化与序列化代码不匹配,最好将其留给正确构建的序列化程序。
  • 嗯,它是标准化的,我必须对用户本身进行操作,否则我会遇到更多问题。另一件事是因为学校,我不允许使用序列化程序......

标签: c# asp.net session type-conversion razor-pages


【解决方案1】:

目前,您将编码值排序为一个长字节数组,当您对它们进行解码时,您不知道它们从哪里开始或结束 - 所以如果您添加一个分隔符,您可以这样做:我在这里使用\0:

byte[] LanguagesInBytes = languages
  .SelectMany(s => System.Text.Encoding.ASCII.GetBytes(s + "\0"))
  .ToArray();

然后,解码它们:

List<string> output = new List<string>();
string language = string.Empty;
for (int i = 0; i < LanguagesInBytes.Length; i++) {
    var item = LanguagesInBytes[i];
    if (item == 0) {
        output.Add(language);
        language = string.Empty;
    }
    else {
        language += System.Text.Encoding.ASCII.GetString(new[] { item });
    }   
}

另请注意,将值存储为 Ascii 意味着 ö 等扩展字符会在此过程中丢失。

【讨论】:

  • 是否可以传递 ü、ö 或 ä 之类的字母?因为使用语言“Französisch”我解码“Fran?sisch”,我尝试了 UTF8,但我仍然无法工作......
  • Encoding.GetEncoding(28591); 会做到的
【解决方案2】:

在byte[] 集合上调用.ToArray() 将返回byte[][](本质上是一个字节数组)

第二部分已接近,但您需要按如下方式进行更改。

这是将它从对象转换为字节[][]

var LanguagesByte = (byte[][])HttpContext.Session.Get("AllowedLanguages");

然后我们必须从每个数组中检索字符串,如下所示

for (int i = 0; i < LanguagesByte.Length; i++)
{
     String str = Encoding.ASCII.GetString(LanguagesByte[i]);
     Languages.Add(str);
}

你也可以使用 linq 来实现这一点

List<string> Languages = LanguageByte.Select(x => Encoding.ASCII.GetString(x)).ToList()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    相关资源
    最近更新 更多