KSler
KSler

Reputation: 23

Converting a Byte[] from a Session back to a List<String> in c#

I try to save a List in a Session by converting it into a Byte[]. But when i try to Convert it back to a List i only get some random Numbers. This is the only way i can save the list with the languages in it.

Below the Code where i convert and save it in the session

   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);
        }

Here is the Code where i try to get it back into an Arraylist or any other type of list with strings is possible

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

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

The List should look like before after i convert it back to display it on a page. Is this even the right way to do it or am i completly wrong?

Upvotes: 1

Views: 855

Answers (2)

stuartd
stuartd

Reputation: 73293

Currently you're sorting the encoded values as one long byte array, and when you decode them you don't know where they start or end - so if you add a delimiter, you can do this: here I'm using \0:

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

Then, to decode them:

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 });
    }   
}

Also note that storing the values as Ascii means the extended characters like ö are lost in the process.

Upvotes: 4

Ben
Ben

Reputation: 787

Calling .ToArray() on a byte[] collection will return a byte[][] (Essentially an array of byte arrays)

The second part is close but you will need to change it as bellow.

This is to cast it from object to byte[][]

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

Then we have to retrieve the strings from each array as below

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

you could use linq to achieve this aswell

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

Upvotes: 0

Related Questions