question

RezaJaferi1992 avatar image
0 Votes"
RezaJaferi1992 asked RezaJaferi1992 edited

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

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


dotnet-csharp
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Can we see your table schema? Here is what I'm using for the code sample.
67912-11111111111.png


0 Votes 0 ·
11111111111.png (15.3 KiB)
RezaJaferi1992 avatar image
0 Votes"
RezaJaferi1992 answered RezaJaferi1992 published

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.






5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered DanielZhang-MSFT commented

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




· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It still gives an error

0 Votes 0 ·

Hi @64936295 ,

 >>BookImage='"+ (BitmapImage)BookImage.Source

You can try to convert "BookImage.Source" to an array and then update, instead of BitmapImage type.
Best Regards,
Daniel Zhang

0 Votes 0 ·
Viorel-1 avatar image
0 Votes"
Viorel-1 answered RezaJaferi1992 commented

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.

· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Your code gives this error : No imaging component suitable to complete this operation was found.'

0 Votes 0 ·

Maybe the problem is how to update the image? What is your opinion?

0 Votes 0 ·

Look at the paragraph related to updating information and image! "',BookImage='"+ "@Image"

0 Votes 0 ·

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

0 Votes 0 ·