Problem retrieving the image after updating the Access database (System.ArgumentException: 'Parameter is not valid.')

رضا جافری 1,296 Reputation points
2021-02-12T19:54:34.947+00:00

First and foremost, I apologize for my grammatical errors; my first language is Persian (Iran).

I use the following code to insert the image and retrieve it from the Access database, and I have no problem retrieving it after inserting the image.

       BitmapImage BM;
       private void UploadButton_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
       {
        System.Windows.Forms.OpenFileDialog OpenFileDialog = new System.Windows.Forms.OpenFileDialog();
        OpenFileDialog.AutoUpgradeEnabled = false;
        if (App.EnumLanguage.Equals(AllLanguage.English))
        {
            OpenFileDialog.Title = "Selecting Image";
        }
        else
        {
            OpenFileDialog.Title = "انتخاب تصویر";
        }
        OpenFileDialog.Filter = "JPG(*.jpg)|*.jpg|BMP(*.bmp)|*.bmp|GIF(*.gif)|*.gif|PNG(*.png)|*.png|All Files|*.*";
        if (OpenFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            var IMG = System.Drawing.Image.FromFile(OpenFileDialog.FileName);
            BM = new BitmapImage(new Uri(OpenFileDialog.FileName));
            BitmapImage BitMapImage = new BitmapImage();
            BitMapImage.BeginInit();
            System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream();
            IMG.Save(MemoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
            MemoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            BitMapImage.StreamSource = MemoryStream;
            BitMapImage.EndInit();
            BookImage.Source = BitMapImage;
            OpenFileDialog.Dispose();
        }
       }
       private static byte[] ImageToBytes(BitmapImage image)
       {
        byte[] Data;
        JpegBitmapEncoder JpegEncoder = new JpegBitmapEncoder();
        JpegEncoder.Frames.Add(BitmapFrame.Create(image));
        using (System.IO.MemoryStream MS = new System.IO.MemoryStream())
        {
            JpegEncoder.Save(MS);
            Data = MS.ToArray();
        }
        return Data;
       }
       private BitmapImage GetImageFromBytes(byte[] bytes)
       {
        System.IO.MemoryStream Stream = new System.IO.MemoryStream();
        Stream.Write(bytes, 0, bytes.Length);
        Stream.Position = 0;
        System.Drawing.Image img = System.Drawing.Image.FromStream(Stream);
        BitmapImage bitImage = new BitmapImage();
        bitImage.BeginInit();
        System.IO.MemoryStream MS = new System.IO.MemoryStream();
        img.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);
        MS.Seek(0, System.IO.SeekOrigin.Begin);
        bitImage.StreamSource = MS;
        bitImage.EndInit();
        return bitImage;
       }
       private void Add_Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
       {
        OleDbConnect.Open();
        if (BM != null)
        {
            byte[] Image_Bytes = ImageToBytes(BM);
            OleDbParameter Parameter = new OleDbParameter();
            Parameter.OleDbType = OleDbType.Binary;
            Parameter.ParameterName = "Image";
            Parameter.Value = Image_Bytes;
            OleDbCommand OleDbCommand_Insert = new OleDbCommand("Insert Into [BookTable](BookName,Publisher,Category,IDNumber,Status,HistoryTaken,RecipientName,ReturnDate,BookImage)values('" + BookName_TextBox.Text + "','" + Publisher_TextBox.Text + "','" + Category_ComboBox.Text + "','" + IDNumber_TextBox.Text + "','" + Status_ComboBox.Text + "','" + HistoryTaken_TextBox.Text + "','" + RecipientName_TextBox.Text + "','" + ReturnDate_TextBox.Text + "',@Image)", OleDbConnect);
            OleDbCommand_Insert.Parameters.Add(Parameter);
            OleDbCommand_Insert.ExecuteScalar();
        }
        OleDbConnect.Close();
       }

       \\\ retrieving information from Access Database

       OleDbCommand OleDCmd = new OleDbCommand("Select * From BookTable Where IDNumber='" + Search_ComboBox.Text.Trim() + "'", OleDbConnect);
       OleDCmd.CommandType = System.Data.CommandType.Text;
       OleDbConnect.Open();
       OleDbDataReader DataReader = OleDCmd.ExecuteReader();
       while (DataReader.Read())
       {
         BookName_TextBox.Text = DataReader[0].ToString();
         Publisher_TextBox.Text = DataReader[1].ToString();
         Category_ComboBox.Text = DataReader[2].ToString();
         IDNumber_TextBox.Text = DataReader[3].ToString();
         Status_ComboBox.Text = DataReader[4].ToString();
         HistoryTaken_TextBox.Text = DataReader[5].ToString();
         RecipientName_TextBox.Text = DataReader[6].ToString();
         ReturnDate_TextBox.Text = DataReader[7].ToString();
         BitmapImage BMP = GetImageFromBytes((byte[])DataReader[8]);
         BookImage.Source = BMP;
       }

But when I use the following commands to update the image and other information, this error is displayed when I want to retrieve the information.

            byte[] Image_Bytes = ImageToBytes(BM);
            OleDbParameter Parameter = new OleDbParameter();
            Parameter.OleDbType = OleDbType.Binary;
            Parameter.ParameterName = "Image";
            Parameter.Value = Image_Bytes;
            OleDbCommand OleDbCommand_Update = new OleDbCommand("Update [BookTable] Set BookName='"+BookName_TextBox.Text.Trim()+"',Publisher='"+Publisher_TextBox.Text.Trim()+"',Category='"+Category_ComboBox.Text.Trim()+"',Status='"+Status_ComboBox.Text.Trim()+"',HistoryTaken='"+HistoryTaken_TextBox.Text.Trim()+"',RecipientName='"+RecipientName_TextBox.Text.Trim()+"',ReturnDate='"+ReturnDate_TextBox.Text.Trim() +"',BookImage='"+ (BitmapImage)BookImage.Source + "'Where IDNumber='" + IDNumber_TextBox.Text.Trim()+ "'", OleDbConnect);
            OleDbCommand_Update.Parameters.Add(Parameter);
            OleDbCommand_Update.ExecuteScalar();

System.ArgumentException: 'Parameter is not valid.' Line 6 gives an error

            private BitmapImage GetImageFromBytes(byte[] bytes)
            {
             System.IO.MemoryStream Stream = new System.IO.MemoryStream();
             Stream.Write(bytes, 0, bytes.Length);
             Stream.Position = 0;
             System.Drawing.Image img = System.Drawing.Image.FromStream(Stream);\\System.ArgumentException: 'Parameter is not valid.'
             BitmapImage bitImage = new BitmapImage();
             bitImage.BeginInit();
             System.IO.MemoryStream MS = new System.IO.MemoryStream();
             img.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);
             MS.Seek(0, System.IO.SeekOrigin.Begin);
             bitImage.StreamSource = MS;
             bitImage.EndInit();
             return bitImage;
            }

In short:in insert command i have no problem to retrieve image but in update command i have problem to retrieve image.

In my opinion, the Update command does not save the image properly in the Access database.

Thanks

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
{count} votes

Accepted answer
  1. رضا جافری 1,296 Reputation points
    2021-02-16T19:38:33.26+00:00

    Hooray, hooray I found the solution (I found it myself). If IDNumber data type as be number data type in Access Database , this code works 100%.

    Just Replace this code...

    OleDbCommand OleDbCommand_Update = new OleDbCommand("Update [BookTable] Set BookName='"+BookName_TextBox.Text.Trim()+"',Publisher='"+Publisher_TextBox.Text.Trim()+"',Category='"+Category_ComboBox.Text.Trim()+"',Status='"+Status_ComboBox.Text.Trim()+"',HistoryTaken='"+HistoryTaken_TextBox.Text.Trim()+"',RecipientName='"+RecipientName_TextBox.Text.Trim()+"',ReturnDate='"+ReturnDate_TextBox.Text.Trim() +"',BookImage='"+ "@Image" + "'Where IDNumber='" + IDNumber_TextBox.Text.Trim()+ "'", OleDbConnect);
    

    With the following code (this is how the UPDATE Query command should be written)

    OleDbCommand OleDbCommand_Update = new OleDbCommand("Update [BookTable] Set BookImage=Image,BookName='" +BookWindow.BookName_TextBox.Text.Trim() + "',Publisher='" + BookWindow.Publisher_TextBox.Text.Trim() + "',Category='" + BookWindow.Category_ComboBox.Text.Trim() + "',Status='" + BookWindow.Status_ComboBox.Text.Trim() + "',HistoryTaken='" + BookWindow.HistoryTaken_TextBox.Text.Trim() + "',RecipientName='" + BookWindow.RecipientName_TextBox.Text.Trim() + "',ReturnDate='" + BookWindow.ReturnDate_TextBox.Text.Trim() + "'Where IDNumber=" + BookWindow.IDNumber_TextBox.Text.Trim(), OleDbConnect);
    

    I tested a lot until I finally got the result. Thanks a lot for your help.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Viorel 114.7K Reputation points
    2021-02-12T20:39:17.157+00:00

    Maybe you should redesign the function:

    private BitmapImage GetImageFromBytes(byte[] bytes)
    {
       var ms = new System.IO.MemoryStream(bytes);
       var bitImage = new BitmapImage();
       bitImage.BeginInit();
       bitImage.StreamSource = ms;
       bitImage.EndInit();
    
       return bitImage;
    }
    

    Show the errors if this still does not work.


  2. Karen Payne MVP 35,386 Reputation points
    2021-02-12T23:49:25.073+00:00

    Hello,

    See the following project source code on GitHub. The actual insert is hard-coded but that doesn't matter as using a OpenFileDialog to select an image works no different.

    Here are parts of the code but not all of it, if you want to use it study the code, copy and use.

    Class to read and insert records

    using System;  
    using System.Data;  
    using System.Data.OleDb;  
    using System.IO;  
    using static WorkingWithMsAccessImages.Classes.ConversionModule;  
      
    namespace WorkingWithMsAccessImages.Classes  
    {  
        public class Operations  
        {  
            public DataTable PictureDataTable { get; set; }  
            public DataTable CategoriesDataTable { get; set; }  
            public string ConnectionString =   
                "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database1.accdb";  
      
            public PictureItem AddImage(string fileName, int category, string description)  
            {  
      
                var results = new PictureItem() {Success = false};  
                      
                if (!File.Exists(fileName))  
                {  
                    results.ErrorMessage = "Failed to find file";  
                    return results;  
                }  
                  
      
                results.ImageBytes = FileImageBytes(fileName);  
                  
                using (var cn = new OleDbConnection { ConnectionString = ConnectionString })  
                {  
                    using (var cmd = new OleDbCommand { Connection = cn })  
                    {  
                        cmd.CommandText =   
                            "INSERT INTO Pictures (Category,Picture,Description,BaseName,FileExtension) " +   
                            "Values (@Category,@Picture,@Description,@BaseName,@FileExtension)";  
      
                        cmd.Parameters.AddRange(new OleDbParameter[]  
                        {  
                            new OleDbParameter  
                            {  
                                ParameterName = "@Category",  
                                DbType = DbType.Int32,  
                                Value = category  
                            },  
                            new OleDbParameter  
                            {  
                                ParameterName = "@Picture",  
                                OleDbType = OleDbType.Binary,  
                                Value = results.ImageBytes  
                            },  
                            new OleDbParameter  
                            {  
                                ParameterName = "@Description",  
                                DbType = DbType.String,  
                                Value = description  
                            },  
                            new OleDbParameter  
                            {  
                                ParameterName = "@BaseName",  
                                DbType = DbType.String,  
                                Value = System.IO.Path.GetFileNameWithoutExtension(fileName).ToLower()  
                            },  
                            new OleDbParameter  
                            {  
                                ParameterName = "@FileExtension",  
                                DbType = DbType.String,  
                                Value = System.IO.Path.GetExtension(fileName).Replace(".", "").ToLower()  
                            }  
                        });  
      
                        try  
                        {  
                            cn.Open();  
                            var affected = cmd.ExecuteNonQuery();  
                            if (affected == 1)  
                            {  
                                cmd.CommandText = "Select @@Identity";  
                                results.Success = true;  
                                results.Identifier = (int)cmd.ExecuteScalar();  
                                return results;  
                            }  
                            else  
                            {  
                                return results;  
                            }  
                        }  
                        catch (Exception ex)  
                        {  
                            results.ErrorMessage = ex.Message;  
                            return results;  
                        }  
                    }  
                }  
            }  
            public void LoadImages()  
            {  
                using (var cn = new OleDbConnection { ConnectionString = ConnectionString })  
                {  
                    using (var cmd = new OleDbCommand { Connection = cn })  
                    {  
                        cmd.CommandText = "SELECT Identifier, Category FROM  Category ORDER BY Category";  
      
                        CategoriesDataTable = new DataTable();  
                        cn.Open();  
                        CategoriesDataTable.Load(cmd.ExecuteReader());  
      
                        DataRow dr = CategoriesDataTable.NewRow();  
                        dr["Identifier"] = 0;  
                        dr["Category"] = "ALL";  
                        CategoriesDataTable.Rows.InsertAt(dr, 0);  
      
                        cmd.CommandText =   
                            "SELECT Identifier, Category, Picture, Description, " +   
                            "BaseName,FileExtension,BaseName + '.' + FileExtension As FullFileName FROM Pictures;";  
      
                        PictureDataTable = new DataTable();  
      
                        PictureDataTable.Load(cmd.ExecuteReader());  
                        PictureDataTable.Columns["Picture"].ColumnMapping = MappingType.Hidden;  
                    }  
                }  
            }  
            public Tuple<string, byte[]> LoadSingleImage(int primaryKey)  
            {  
                byte[] imageBytes;  
      
                using (var cn = new OleDbConnection { ConnectionString = ConnectionString })  
                {  
                    using (var cmd = new OleDbCommand { Connection = cn })  
                    {  
                        cmd.CommandText =   
                            "SELECT Identifier, Category, Picture, Description," +   
                            " BaseName,FileExtension,BaseName + '.' + FileExtension As FullFileName FROM Pictures WHERE Identifier = ?";  
                          
                        cmd.Parameters.AddWithValue("?", primaryKey);  
      
                        var dt = new DataTable();  
                        cn.Open();  
                        dt.Load(cmd.ExecuteReader());  
                        imageBytes = dt.Rows[0].Field<byte[]>("Picture");  
                        var fileName = dt.Rows[0].Field<string>("FullFileName");  
      
                        return new Tuple<string, byte[]>(fileName, imageBytes);  
      
                    }  
                }  
            }  
      
            public Operations()  
            {  
                LoadImages();  
            }  
        }  
    }  
    

    Conversion helpers

    using System;  
    using System.IO;  
      
    namespace WorkingWithMsAccessImages.Classes  
    {  
        public static class ConversionModule  
        {  
            /// <summary>  
            /// Saves bytes to a new image file  
            /// </summary>  
            /// <param name="pImageData"></param>  
            /// <param name="pFilePath"></param>  
            /// <returns></returns>  
            /// <remarks></remarks>  
            public static bool ConvertBytesToImageFile(byte[] pImageData, string pFilePath)  
            {  
                try  
                {  
                    var fileStream = new FileStream(pFilePath, FileMode.OpenOrCreate, FileAccess.Write);  
                    var binaryWriter = new BinaryWriter(fileStream);  
      
                    binaryWriter.Write(pImageData);  
                    binaryWriter.Flush();  
                    binaryWriter.Close();  
                    fileStream.Close();  
                    binaryWriter = null;  
                    fileStream.Dispose();  
      
                    return true;  
      
                }  
                catch (Exception ex)  
                {  
                    return false;  
                }  
      
            }  
            public static byte[] FileImageBytes(string pFileName)  
            {  
                var fileStream = new FileStream(pFileName, FileMode.Open, FileAccess.Read, FileShare.Read);  
                var imageStream = new StreamReader(fileStream);  
                byte[] byteArray = new byte[((int)(fileStream.Length - 1)) + 1];  
      
                fileStream.Read(byteArray, 0, (int)fileStream.Length);  
      
                return byteArray;  
      
            }  
        }  
    }  
    

    Return type for inserting image

    namespace WorkingWithMsAccessImages.Classes  
    {  
        public class PictureItem  
        {  
            public int Identifier { get; set; }  
            public byte[] ImageBytes { get; set; }  
            public bool Success { get; set; }  
            public string ErrorMessage { get; set; }  
        }  
    }  
    

    Form code

    using System;  
    using System.Data;  
    using System.Drawing;  
    using System.IO;  
    using System.Windows.Forms;  
    using WorkingWithMsAccessImages.Classes;  
      
    namespace WorkingWithMsAccessImages  
    {  
        public partial class Form1 : Form  
        {  
            private readonly BindingSource _bindingSource = new BindingSource();  
            public Form1()  
            {  
                InitializeComponent();  
                  
                _bindingSource.PositionChanged += BindingSourceOnPositionChanged;  
                  
                Shown += OnShown;  
            }  
      
            private void OnShown(object sender, EventArgs e)  
            {  
                var ops = new Operations();  
                  
                _bindingSource.DataSource = ops.PictureDataTable;  
                dataGridView1.DataSource = _bindingSource;  
                dataGridView1.ExpandColumns();  
            }  
      
            private void BindingSourceOnPositionChanged(object sender, EventArgs e)  
            {  
                if (_bindingSource.Current != null)  
                {  
                    pictureBox1.Image = Image.FromStream(new MemoryStream(  
                        ((DataRowView)_bindingSource.Current).Row.Field<byte[]>("Picture")));  
      
                }  
            }  
      
            private void AddImageButton_Click(object sender, EventArgs e)  
            {  
                var ops = new Operations();  
      
                var results = ops.AddImage("ErrorForm.png", 0, "Test");  
                if (results.Success)  
                {  
                    var values = ops.LoadSingleImage(results.Identifier);  
                    var table = (DataTable) _bindingSource.DataSource;  
                    table.Rows.Add(results.Identifier, 0, results.ImageBytes);  
                    _bindingSource.MoveLast();  
                }  
                else  
                {  
                    MessageBox.Show(!string.IsNullOrWhiteSpace(results.ErrorMessage) ?   
                        $"Failed to add image\n{results.ErrorMessage}" :   
                        "Failed to add image\n");  
                }  
            }  
        }  
    }  
    

    Update

    Added simple update method

    67743-imagedatagridview.png

    public PictureItem UpdateCurrentDescription(int primaryKey, string description)  
    {  
        var results = new PictureItem() { Success = false };  
          
        using (var cn = new OleDbConnection {ConnectionString = ConnectionString})  
        {  
            using (var cmd = new OleDbCommand {Connection = cn})  
            {  
                cmd.CommandText =   
                    "UPDATE Pictures SET Description = @Description " +   
                    "WHERE Identifier = @Identifier";  
      
                var descriptionParameter = new OleDbParameter  
                {  
                    DbType = DbType.String,  
                    ParameterName = "@Description",  
                    Value = description  
                };  
      
                cmd.Parameters.Add(descriptionParameter);  
                  
                var identifierParameter = new OleDbParameter  
                {  
                    DbType = DbType.String,  
                    ParameterName = "@Identifier",  
                    Value = primaryKey  
                };  
      
                cmd.Parameters.Add(identifierParameter);  
      
                try  
                {  
                    cn.Open();  
                    int affected = cmd.ExecuteNonQuery();  
                    if (affected == 1)  
                    {  
                        results.Success = true;  
                    }  
                }  
                catch (Exception e)  
                {  
                    results.ErrorMessage = e.Message;  
                    return results;  
                }  
      
            }  
        }  
      
        return results;  
    }