Base64 string saves in database as null C#

632 Views Asked by At

I have problem where I convert image into Base64 string and saves it as string in database, but it returns nothing. Base64Text is global variable, also variable is not null I tested it with button to fill textbox, it just saves as "" into database.

Here is model of table in database

    public class Product
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public double ProductPrice { get; set; }
        public int ProductAmount { get; set; }
        public string ProductImage { get; set; } // Used for storing image string
        public int userID { get; set; }
    }
// Here is image converter
        private void btnAddImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "Image Files(*.BMP;*.JPG;*.PNG;*.JPEG)|*.BMP;*.JPG;*.PNG;*.JPEG" +
                "|All files(*.*)|*.*";
            dialog.CheckFileExists = true;
            dialog.Multiselect = false;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var image = new Bitmap(dialog.FileName);
                pictureBoxProductImage.Show();
                pictureBoxProductImage.Image = (Image)image;

                byte[] imageArray = System.IO.File.ReadAllBytes(dialog.FileName);
                base64Text = Convert.ToBase64String(imageArray);
            }
        }
// Here is saving image using Entity framework
        private void btnAddProduct_Click(object sender, EventArgs e)
        {
            string imagePath = base64Text;
            if (txtBoxProductName.Text == null || txtBoxProductPrice.Text == null || txtBoxProductQuantity.Text == null || imagePath == null || imagePath == "")
            {
                MessageBox.Show("Please fill required information!", "", MessageBoxButtons.OK);
            }
            else
            {
                model.ProductName = txtBoxProductName.Text;
                model.ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text);
                model.ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text);
                model.ProductImage = imagePath;
                model.userID = id;

                using (var context = new ProductContext())
                {
                    context.Products.Add(model);
                    context.SaveChanges();
                }
                MessageBox.Show("Product sucesffuly added to database!", "", MessageBoxButtons.OK);
                Clear();
            }
        }
1

There are 1 best solutions below

0
On

You look to be dangerously mixing variable scopes. Considering this code:

model.ProductName = txtBoxProductName.Text;
model.ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text);
model.ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text);
model.ProductImage = imagePath;
model.userID = id;

using (var context = new ProductContext())
{
    context.Products.Add(model);
    context.SaveChanges();
}

'model' is not scoped to this method.

I do not recommend binding views to Entities as view models, instead use a Plain-old C# ViewModel class to avoid confusion and laboring entities with multiple concerns. (Property change tracking, UI validation behaviour, etc.)

What it should look more like:

using (var context = new ProductContext())
{
    var product = new Product
    {
        UserId = id,
        ProductName = txtBoxProductName.Text,
        ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text),
        ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text),
        ProductImage = hiddenImage.Text, // Something in the scope of the view storing the image Base64 content, not a global variable.
    };
    context.Products.Add(product);
    context.SaveChanges();
}

When adding an entity you want to ensure that you are dealing with a new instance of that entity, not a reference. model could be a reference to another entity that the context is already tracking which means you can end up replacing values on a completely different record when you think you're adding a new row. Also, since you are scoping a new DbContext instance, any entity reference from outside that scope could result in exceptions.

Avoid global variables for any of the details. When you select an image, ensure that the Base64 is store somewhere in the scope of the app page or bound view model. If after these changes there is still no ProductImage being saved, then I would look at the Entity declaration to ensure it isn't marked as Ignore, and consider looking at using a profiler to review the SQL being generated to be sure the field is being included and what value is being sent.