none
Converting data of datacolumn type Byte[] back to Byte Array RRS feed

  • Question

  • Hi, I'm storing a serialized object in a datatable. The column is of type String.Byte[]

    Here's how the data is stored:

    Dim ms As New System.IO.MemoryStream
    Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    bf.Serialize(ms, myObject)
    ms.Position = 0
    DataSet.Tables(0).Rows(0)("QualEvaluationData") = ms.ToArray

    Which seems to work fine. When I go to deserialize the data with the following:

    Dim ms As New System.IO.MemoryStream(CType(DataSet.Tables(0).Rows(0)("QualEvaluationData"), Byte()))
    Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
    Dim myObject As MyObjectType = bf.Deserialize(ms)
    Return myObject

    I get the following conversion error on the first line: Unable to cast object of type 'System.String' to type 'System.Byte[]'.

    Any thoughts?

    Thursday, March 10, 2011 6:09 AM

Answers

  • Hi naht,

     

    Thanks for your feedback.

    During solving this issue, I found some solutions about  Unable to cast object of type 'System.String' to type 'System.Byte[]' in the codeproject.

    The original code as below:

      cmd.CommandText = "select_student";
                cmd.Parameters.AddWithValue("@sno",textBox1.Text);
                da = new SqlDataAdapter(cmd);
                ds = new DataSet();
                da.Fill(ds, "student");
                if (ds.Tables[0].Rows.Count > 0)
                {
                    textBox2.Text = ds.Tables[0].Rows[0][0].ToString();
                    textBox3.Text = ds.Tables[0].Rows[0][1].ToString();
                    if (ds.Tables[0].Rows[0][2] != System.DBNull.Value)
                    {
                        byte[] data = (byte[])ds.Tables[0].Rows[0][2];
                        ms = new MemoryStream(data);
                        pictureBox1.Image = Image.FromStream(ms);
                    }
                    else
                        pictureBox1.Image = null;
                }
                else
                    MessageBox.Show("Record does not exixts");

    These codes can reflect the error.

    Solution 1

     

    It looks like in your database you your image column
    (ds.Tables[0].Rows[0][2])
    has data type varchar rather than image(or varbinary(max)).
    When you try to cast the string(varchar) into array of bytes it returns you the error.
    If this is so it will not work.

    You have to change the data type for the image column into the proper format and try the code again.

    Solution 2

     

    A simple cast is not enough in this case.

    Try :
    byte[] data = System.Text.UTF8Encoding.GetBytes(ds.Tables[0].Rows[0][2]);
    I used UTF8Encoding as an example, substitute it wirh your needed encoding.

    Solution 3

     

    If your database is holding the field as a NVCHAR or similar, then it is indeed a string. In which case use
    string s = (string)ds.Tables[0].Rows[0][2];
    byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
    ms = new MemoryStream(data);
    pictureBox1.Image = Image.FromStream(ms);
    BTW: try not to use "magic numbers" for your code - it makes it hard to read and understand when you come back to maintain it.
    Tables[0]
    and
    Rows[0]
    are ok - ish - but
    Rows[0][2]
    is not as readable as
    Rows[0]["DataStream"]
    More infomation, see here.
    I hoep this can help.
    have a nice day,

    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, March 16, 2011 7:19 AM
    Moderator

All replies

  • Hello naht,

     

    Welcome to the MSDN Forum and thanks for posting here.

    According to your description, I think a sample from CodeProject can help you. In this sample we are storing a dataset object in a binary file using object serializtion , and after serializtion process we will make deserialization to get all inforamtion from tables without connectiing to database

    Here it is:

    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Runtime.Serialization.Formatters.Binary
    Imports System.IO
    Module Module1
    Private connStr As String = "Data Source=.\SQLEXPRESS;Database=Northwind;Integrated Security=True"
    Private _file As String = "C:\ds.dat"
    Sub Main()
    Dim obj As StoringDataSetInFile = New StoringDataSetInFile(connStr, _file)
    obj.StoreInFile()
    obj.GetFromFile()
    Dim employees As List(Of String) = obj.GetDataFromDataSet
    For Each employee As String In employees
    Console.WriteLine(employee)
    Next
    Console.Read()
    End Sub
    End
    Module
    Public
    Class StoringDataSetInFile
    Private data As DataSet
    Private connStr As String
    Private _file As String
    Sub New(ByVal connStr As String, ByVal _file As String)
    Me.connStr = connStr
    Me._file = _file
    End Sub
    Sub StoreInFile()
    Dim conn As New SqlConnection
    conn.ConnectionString = connStr
    Try
    conn.Open()
    Dim cmd As New SqlCommand
    cmd.Connection = conn
    cmd.CommandText = "Select * From Employees"
    Dim ada As New SqlDataAdapter
    ada.SelectCommand = cmd
    data = New DataSet
    ada.Fill(data, "Employees")
    conn.Close()
    Dim fs As FileStream = File.Create(Me._file)
    Dim binFormatter As New BinaryFormatter
    binFormatter.Serialize(fs, data)
    fs.Close()
    binFormatter = Nothing
    data = Nothing
    Catch ex As Exception
    Console.WriteLine("Error :" & ex.ToString)
    End Try
    End Sub
    Sub GetFromFile()
    Dim fs As FileStream = File.Open(Me._file, FileMode.Open)
    Dim binFormatter As New BinaryFormatter
    data = CType(binFormatter.Deserialize(fs), DataSet)
    fs.Close()
    End Sub
    Function GetDataFromDataSet() As List(Of String)
    Dim dt As New DataTable
    dt = data.Tables("Employees")
    Dim lstFullNames As New List(Of String)
    For Each _row As DataRow In dt.Rows
    Dim str As String = _row("firstname") & " " & _row("lastname")
    lstFullNames.Add(str)
    Next
    Return lstFullNames
    End Function
    End
    Class

    I hope this can help you.

     

    Have a nice weekend!


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Sunday, March 13, 2011 7:40 AM
    Moderator
  • Thanks Jackie, that's kind of close, and i didn't have any problem storing a serialized dataset to a file, but the example I'm working on is serializing an object to a field in the dataset so that it can be stored in the database.  Maybe I'm going about it wrong.  The object is a very expensive object to create (it's actually a list of objects), and I want to be able to store different versions of it (along with the parameters used to create it) in a table in the database so that other users can recall the data.
    Monday, March 14, 2011 6:02 AM
  • Hi naht,

     

    Thanks for your feedback.

    During solving this issue, I found some solutions about  Unable to cast object of type 'System.String' to type 'System.Byte[]' in the codeproject.

    The original code as below:

      cmd.CommandText = "select_student";
                cmd.Parameters.AddWithValue("@sno",textBox1.Text);
                da = new SqlDataAdapter(cmd);
                ds = new DataSet();
                da.Fill(ds, "student");
                if (ds.Tables[0].Rows.Count > 0)
                {
                    textBox2.Text = ds.Tables[0].Rows[0][0].ToString();
                    textBox3.Text = ds.Tables[0].Rows[0][1].ToString();
                    if (ds.Tables[0].Rows[0][2] != System.DBNull.Value)
                    {
                        byte[] data = (byte[])ds.Tables[0].Rows[0][2];
                        ms = new MemoryStream(data);
                        pictureBox1.Image = Image.FromStream(ms);
                    }
                    else
                        pictureBox1.Image = null;
                }
                else
                    MessageBox.Show("Record does not exixts");

    These codes can reflect the error.

    Solution 1

     

    It looks like in your database you your image column
    (ds.Tables[0].Rows[0][2])
    has data type varchar rather than image(or varbinary(max)).
    When you try to cast the string(varchar) into array of bytes it returns you the error.
    If this is so it will not work.

    You have to change the data type for the image column into the proper format and try the code again.

    Solution 2

     

    A simple cast is not enough in this case.

    Try :
    byte[] data = System.Text.UTF8Encoding.GetBytes(ds.Tables[0].Rows[0][2]);
    I used UTF8Encoding as an example, substitute it wirh your needed encoding.

    Solution 3

     

    If your database is holding the field as a NVCHAR or similar, then it is indeed a string. In which case use
    string s = (string)ds.Tables[0].Rows[0][2];
    byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
    ms = new MemoryStream(data);
    pictureBox1.Image = Image.FromStream(ms);
    BTW: try not to use "magic numbers" for your code - it makes it hard to read and understand when you come back to maintain it.
    Tables[0]
    and
    Rows[0]
    are ok - ish - but
    Rows[0][2]
    is not as readable as
    Rows[0]["DataStream"]
    More infomation, see here.
    I hoep this can help.
    have a nice day,

    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, March 16, 2011 7:19 AM
    Moderator