Storing C# Converted base64 as SQL Server varbinary(max) - c#

I've got an angular webapp where I accept images in base64 and store them in T-SQL varbinary. However, I have existing data stored in SQL-Server that appears to be in a different binary. I need both binaries to work with the same Read/Update methods in C#.
In the service I'm trying to convert a base64 string to SQL Server's varbinary and vice versa.
Manually in SSMS, I can take just the base64 string and insert into a row like this:
Cast(#base64ImgStr as varbinary(max))
But the result is different when I try to insert from C#:
Convert.FromBase64String(base64);
(same input). Since the binary is different the image doesn't show. I need a method in C# that provides the same binary as the one in T-SQL.
I must be around the solution, since I can cast and get the proper base64 in SQL Server (again, not in C#) like this:
cast('' as xml).value('xs:base64Binary(sql:variable("#source"))', 'varchar(max)')
Instead of base64 I get back Unicode symbols, otherwise I'd paste in an example.
I need to get the base64 without calling the SQL Server base64Binary method, because my service reads images like this:
Encoding.ASCII.GetString(varbinary)
If I convert the manually inserted varbinary (Cast(#base64ImgStr as varbinary(max))) into varchar(max), I get a base64 string and the image displays appropriately in my webapp.
But, this is not so when I use the C# method to create the binary. With the type of varbinary I get from Convert.FromBase64String(base64), I need an intermediate conversion in SQL Server (xs:base64binary) to reverse the binary to base64. With no intermediate conversion I get Unicode symbols and no image displays in the webapp. I don't want an intermediate conversion because I want consistent results whether users upload images or someone inserts images manually.
I don't see a method on the Convert class that gives me the same type of binary. But that seems to be exactly what I need. I suspect Unicode. Please help!

This worked for me:
var image = Convert.FromBase64String(base64);
string hex = BitConverter.ToString(image);
hex = hex.Replace("-", "");
hex = "0x" + hex;
This hex can be saved in a varbinary(MAX) field without casting or converting and will show as an image in the browser.

Related

How to decode MySql blob from backup file?

I got a MySql backup file containing a column like:
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`profilepicture` blob,
)
The content of this row profilepicture is encoded in the backup file to some kind of dump, starting (in a text editor) like this:
INSERT INTO `tbox_account_transaction` VALUES (8,'?\?\?0JFIF\0\0\0\0\0\0[...]');
How can I decode this from the .sql backup file in c#? It is not Base64, but I do not recognize what else it might be. I don't want to restore the backup.sql file to MySql but instead decode the blob from the backup file.
The bytes you are seeing are almost certainly the initial bytes of a JPEG image. The readable string "JFIF" starting at the fifth byte is the clue (see https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format).
Many of the other binary bytes are null or else non-printable characters. All the weird \? or \0 sequences are the client's best effort at representing these bytes on your text display.
The easiest way to access this data is to restore the dump file to a MySQL instance (even a local one running on a laptop), and then use SQL in your C# code to access the binary contents of the profilepicture blob.
Either save the data from one blob to a .jpg file as #Tommaso Belluzzo suggests, or else just display it directly, if you can. I'm not a C# programmer, but it seems there's a Bitmap class for this (see https://msdn.microsoft.com/en-us/library/8tda2c3c(v=vs.85).aspx).
It's outside the scope of a Stack Overflow answer to give a tutorial on how to write SQL in a C# application. There are plenty of resources available for that.
That looks like a jpg file header. Try the following (blob is a String typed variable containing the profilepicture):
using (MemoryStream stream = new MemoryStream(buffer))
{
Image image = Image.FromStream(stream, true, true);
image.Save("C:\\Test.jpg", ImageFormat.Jpeg);
}

Capture signature using HTML5 and save it as image to database

I am just starting to learn Jquery and working on asp.net webform app that will be used on a touchscreen device, and I need to capture user signature, basically user will sign and after hit save, I want their signature to be saved as an image to SQL server database so I can retrieve and display it later on a webpage.
I found this question: Capture Signature using HTML5 and iPad
and the jQuery plugin works great, exactly as I want.
Here the demo: http://szimek.github.io/signature_pad
Here the plug-in: https://github.com/szimek/signature_pad
So on the demo I see after hit "save" you will go to a new tab that display an image of your signed signature, and I noticed that the url is something like
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAApIAAAE+CAYAAAA+vvBuAAAgAElEQVR4Xu3df8i37V0X8I/l0GY5BzZdiWslKhnNUaBR62lBP0htjuiHfz0uROgPmQsH/hE8jiKKjLl/IoLa9k+NMOYyhCRamyM0WI9bUBst5kzbUNfjxBlmaLy389jO+3q......
What does this url mean?
what type of variable will be used to store this in database table (nvarchar, binary...)
3 (MAIN QUESTION). How do I get those data text in code behind C# button click event to store them to a string variable for other purposes. Can someone provide a simple example so i can go from there?
if I am missing something please let me know, as I am looking at the .html file and those .js files in the demo project of that plugin, I am lost.
That URL is in BASE64 format. You can use that long string of characters in the SRC attribute of an image tag and it will be displayed.
To get better performance, the recommended way of storing photos is to store the image on the disk (using some kind of server side language) and then save the name of the file in a database as a CHAR or TEXT.
Not quite sure. I've never used the library before.
That is a Base64 encoded image.
data: says that data is following instead of a URL
image/png; specifies the content "mimetype" the data should be served as
base64, indicates the encoding type of the data
As base64 only uses ASCII characters, a varchar(MAX) would be suitable for storage. No need for nvarchar. I normally store the base64 encoding only (the last part after the comma), and keep the mime-type (e.g. image/png) in a separate field.
There are many options in C#. If you store the base64 part separately, you simplify the code a bit.
Turn it into an image server-side using byte[] imageBytes = System.Convert.FromBase64String(base64data) and creating an image from the byte array and type.
Inject the image into a webpage <img src="#Html.Raw("data:"+ mimetype + "base64," + base64data)"/>
Notes:
As #anthony mentions, your would typically store images as files (or in Blob storage nowadays) and only record the filename/URI. This depends on quantity size & usage.
We have found it convenient, for certain projects requiring extra security, for base64 images to be stored as encoded & encrypted strings in a database.
From comments: To save to, place the string value into a hidden input and update its value. It will then get posted back like any other string. Our own signature plugin just hides the original <input type="text"> it is attached to and puts the value there.
In addition to TrueBlueAussie's answer:
The simplest way to get your string in CodeBehind is:
Declare a HiddenField using ASP and assign a Static ID to it. (Static ID is important since ASP normally assigns automatically generated IDs to each control, and this can get difficult to predict).
Shape your JavaScript function in a way that SignaturePad writes the output base64 image string into this HiddenField. You can for example, use a button "Verify" that calls the Export function of the SignaturePad.
After the string is written into the HiddenField, read it back on CodeBehind. For this, you can use an additional button, for example something like "Save".
There are of course other options which are much more secure/versatile/appropriate, but this might be a good starting point for you.

Converting binary data to .doc file with the images inside it

I have binary data stored in database which I need to convert them back for backup purposes. Most of them are .doc files with images attached in document. My method to restore them is to write binary data to byte string and write those bytes to the file like mydoc.doc. The problem is, it works for txt files and it actually works for text part of .doc file as well. Since most of the .doc files contain jpeg attached, after conversion I get some readable text and random characters which I believe are there for picture attached in doc file. Any help is appreciated. Thanks in advance...
Note: Binary data is stored in image data type in database. Database contains file path and name (which doesn't exist now) and corresponding binary data stored in image type, so from path I can detect the file type that it was before... some of them are .txt (which I was able to convert perfectly), some of them are .doc (which is problem because of attahcmens inside it)
Here is my code:
string s = "D0CF11E0A1B11AE100000000000000000000"; // note: string is for example
var bytes = GetBytesFromByteString(s).ToArray();
File.WriteAllBytes("C:\\temp\\test.doc", bytes);
A .doc file is not a string or even a text or ASCII. It is a raw binary file format.
So if your database cell contains a BLOB (Binary Large Object) simply treat it as an array of bytes and write it out to a (binary) file. No conversions, no encodings, nothing.
Edit
Whoever designed this database, they designed to store all kinds of files as an image (in the sense of memory-dump-image) i.e. a series of raw bytes in a cell of type image.
You should treat these bytes exactly as mentioned above: A series of raw bytes.

Storing an SVG as bytes in DB?

Wee bit of background to set the scene : we've told a client he can provide us with images of any type and we'll put them on his reports. I've just had a quick run through of doing this and found that the reports (and other things between me and them) are all designed to only use SVGs.
I thought I'd struck gold when I found online that you can convert an image from a jpg or PNG into an SVG using free tools but alas I've not yet succeeded in getting an SVG stored as bytes in the DB in a format that allows me to use it again after reading it back out.
Here's a quick timeline of what followed leading up to my problem.
I use an online tool to generate an SVG from a PNG (e.g., MobileFish)
I can open and view it in Firefox and it looks ok
I ultimately need the SVG to be stored as bytes in the DB, from where the report will pull it via a webpage that serves it up as SVG. So I write it as bytes into a SQL data script. The code I use to write these bytes is included below.
I visit said webpage and I get an error that there is an "XML parsing error on Line 1 Column 1" and it shows some of my bytes. They begin "3C73"
I revisit the DB and compare the bytes I've just written there with some pre-existing (and working ones). While my new ones begin "3C73", the others begin "0xFFFE".
I think I've probably just pointed out something really fundamental but it hasn't clicked.
Can someone tell me what I've done that means my bytes aren't stored in the correct encoding/format?
When I open my new SVG in Notepad++ I can see the content includes the following which could be relevant :
<image width="900" height="401" xLink:href="data:image/png;base64,
(base 64 encoded data follows for 600+ lines)
Here's the brains of the code that turns my SVG into the bytes to be stored in DB :
var bytes = File.ReadAllBytes(file);
using (var fs = new StreamWriter(file + ".txt"))
{
foreach (var item in bytes)
{
fs.Write(String.Format("{0:X2}",item));
}
}
Any help appreciated.
Cheers
Two things:
SVGs are vector images, not bitmap files. All that online tool is doing is taking a JPEG and creating a SVG file with a JPEG embedded in it. You aren't really getting the benefit of a true SVG image. If you realise and understand that, then no worries.
SVG files are just text. In theory there is no reason you can't just store them as strings in your db. As long as the column is big enough. However normally if you are storing unstructured files in a db, the preferred column type to use is a "Blob".
http://technet.microsoft.com/en-us/library/bb895234.aspx
Converting your SVG file to hex is just making things slower and doubling the size of your files. Also when you convert back, you have to be very careful about the string encoding you are using. Which, in fact, sounds like the problem you are having.
I am suspecting you are doing it incorrectly. SVG is simply and XML based vector image format. I guess your application might be using SVG image element and you need to convert your png image to base64 encoded string .

strings from DynamoDB that were originally byte arrays have funky values

Now I'm not sure if this is something I'm doing wrong, or something thats happening in DynamoDB..
Basically, Im building a simple registration/login system for my project, saving the userdata/password in a DynamoDB instance with the password hashed using RIPEMD160, and salted as well using C#'s RNGCryptoServiceProvider().
Registration seems to work perfectly fine. the issue is upon login, no matter what, the passwords dont match up, and I think its because I'm getting some funky characters back when pulling the hash/salt back from DynamoDB. First off, both the hash and the salt are byte arrays of length 20, and converted to strings before saved in the database.
These examples are copy/pasted from the dynamo web interface
Example Hash: ">�Bb.ŧ�E���d��Ʀ"
Example Salt: "`���!�!�Hb�m�}e�"
When they're coming back and I debug into the function that pulls back the data from dynamo, both strings have different characters (VS2010 Debugger):
Returned Hash: "u001B>�Bb.ŧ�E��u0003�d�u001C�Ʀ"
Returned Salt: "`���!u000B�!�Hb�u001Dmu0012�u0001}e�"
Seems these u001B, u000B, u001D, u0012, u0003, u001C, and u0001 are sneaking into the returned data, and I'm not entirely sure whats going on?
You shouldn't be trying to convert opaque binary data into a string in this way in the first place. They're not text so don't treat them that way. You're just begging to lose information that way.
Use Convert.ToBase64String(data) instead of Encoding.GetString before putting the data into the database. When you get it out again, use Convert.FromBase64String to retrieve the original binary data.
Alternatively, don't store the data in a text field to start with - use a database field type which is meant to store binary data...

Categories

Resources