1

I want to capture picture from canvas, make it base64 and save it into db. Is it possible to save base64 directly to table? This is where I came already:

VIEW:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var img = document.getElementById("image0");
ctx.drawImage(img, 0, 0);
//drawing image into myCanvas

var imag = canvas.toDataURL("image/png");
//making base64 from that image

document.getElementById('imag').value = imag;
//passing base64 to @Html.TextAreaFor(model => model.IMG, new {id = "imag"}) prior to submitting

MODEL:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;

namespace myApp.Models
{ 
public class MYCLASS
    {
     public int ...
     public string ...
     public string IMG { get; set; }
    }
}

CONTROLLER:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult myImageToDB(MYCLASS myclass)
{

   if (ModelState.IsValid)
   {
      db.MYCLASSs.Add(myclass);
      db.SaveChanges();
      //here it fails on db.SaveChanges()
      return RedirectToAction("Detail", "M35");
   }
   return View(myclass);
}

When submitted I got only this answer from MS VS:

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities.

The problem occured when I have added

public string IMG { get; set; }

into the model. And when I now disable

document.getElementById('imag').value = imag;

everything works just fine.

thx

8
  • What does the model on the server look like? It appears you have specified validation rules. Commented Nov 22, 2013 at 15:28
  • Your error is a EF error, please provide more details Commented Nov 22, 2013 at 15:28
  • I have added some extra details. Pls let me know if something more is needed. thx Commented Nov 22, 2013 at 15:53
  • please look at this question to find out what your validation errors actually are - stackoverflow.com/questions/5400530/… Commented Nov 22, 2013 at 16:36
  • Floradu88, Tommy, so you would say that there is no problem with the code itself but with the EF? Tommy, I will need 'translator' for the link you posted, didn't yet get it from the answers there :) Commented Nov 22, 2013 at 17:24

2 Answers 2

1

Based on your error message, the error is occuring because your model doesn't fit the database rules. For instance, you are sending a null to a non-nullable value or you are trying to put too much information in a column (255 bytes in a 128 byte column). Use the information located in this link to help you discover exactly what property of the entity is failing - Validation failed for one or more entities while saving changes to SQL Server Database using Entity Framework

Now that you have done that, I see that your actual entity error is

IMG Error: The field IMG must be a string or array type with a maximum length of '4000'.

varchar(n|MAX) has a limit of 4000 IF you specify an integer when you declare it (varchar(4000)). However, using varchar(MAX) gives you 2GB of storage in that one field per record. With that, we need to look to see if you are using code first or database first in your EF implementation. If you are using code first, annotate your column with varchar(MAX) like seen below.

[Column(TypeName = "varchar(MAX)")]
public string Img {get;set;}

If you are using database first, then go to your database (Sql Management Studio), right click the table and choose design. Update the image field to varchar(MAX) as the type and save. In order to update EF, open your EF designer, delete the existing Images table, then right click the surface and choose Update model from Database and follow the steps to re-add your table.

EDIT

Based on the OP's response, we should cover how to make a large varchar column in SQL CE as well. For doing code first against SQL CE, use the following code snippet:

[Column(TypeName = "ntext")]
[MaxLength] 
public string Img {get;set;}
Sign up to request clarification or add additional context in comments.

8 Comments

thanks for your detailed answers. That was it. For my app development I use SQL CE (didn't stated it in my Q) so in the end I found out it is ntext for SQL CE (varchar(MAX) then for SQL Server). But works just fine and I have base64 data already stored in my db column :) Final code snippet for SQL CE [Column(TypeName = "ntext")] public string Img {get;set;}
@nevo - awesome, I updated my answer to cover SQL CE as well!
bad news. I, unfortunately, did somehow cripple (shorten) the base64 string before saving it. That's why I was able to save it to "ntext" string as I mentioned above. After I corrected the mistake I again receive the The field IMG must be a string or array type with a maximum length of '4000' error no matter the Img string is ntext. I am afraid that SQL CE will not 'eat' that long string like base64. Or there is some other problem (needs to be decoded/encoded??) ...
@nevo - In addition to the above comment, take a look at this SO question as well - stackoverflow.com/questions/15329877/…
|
0

Is there a reason you need Base64? It adds overhead to having to encode and decode that out of the database. If you can, it may be better to simply store the image data (un-encoded) as a binary blob in the database. That is, if your images are of a small size.

Microsoft provides a good document (https://research.microsoft.com/pubs/64525/tr-2006-45.pdf) called "To BLOB or not to BLOB" about whether you should store images in a database. The basic rule is if you image is 256KB or less, it is OK to store in DB. If bigger than 1MB, then it is better to store the images on the filesystem and serve them directly from there in your server.

MS SQL Server 2012 can automatically manage filesystem storage of binary data for you with its new FILETABLE feature: http://blogs.msdn.com/b/mvpawardprogram/archive/2012/07/23/sql-server-2012-migrating-blobs-to-filetables.aspx

5 Comments

what if they are larger than 256KB but less than 1MB? :)
the reason I want to store it directly to db is that not all records after they are created will be 'saved' for the later. So if I will have images stored in the filesystem, I then need to delete the db record and also image from filesystem instead of just deleting only the db record. And yes, the pictures will be 256KB or less.
nevo, I understand. But if your images are larger than 1MB, your performance may suffer. It's OK, storing in DB is just fine. But for better performance, don't bother with base64, just store as a blob. In SQL Server version prior to 2012, they even offer an "IMAGE" type: technet.microsoft.com/en-us/library/ms187993.aspx If you're fortunate enough to use Server 2012, its new FILETABLE can give you the best of both worlds. It manages the data on the filesystem for you! blogs.msdn.com/b/mvpawardprogram/archive/2012/07/23/…
I would say that I am just curious if this new approach will or will not be easier for programming. Storing images into filesystem I have already tried in my previous app.
@nemik, thanks also for your answers. Wish I have bigger reputation so I will mark your tip as useful. I am keeping the filesystem storing as backup. One never knows :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.