Saving file base64 string in SQL Server database - c#

I working on a file upload, on upload the file is converted to base64 string and this string is sent to an API that saves the string in a SQL Server database table.
The type of the base64 string column in the table is NVARCHAR(MAX) but I noticed when the file is saved, SQL truncates the string such that when you convert online using base64 to image decoder, it produces just part of the whole picture and I noticed that the base64 string before saving to SQL is about 72,000 in character count but after saving it SQL it is reduced to about 4,000 which is responsible for the incomplete image decoded.
Why does SQL truncate the base64 string and what can I do to help my situation?
Here is my base64 conversion code:
public async Task<IActionResult> UploadFile()
{
string base64string;
var myFile = Request.Form.Files["claimFile"];
var filetype = myFile.ContentType;
var filepath = Path.GetTempFileName();
using (var stream = System.IO.File.Create(filepath))
{
await myFile.CopyToAsync(stream);
}
byte[] imageByte = System.IO.File.ReadAllBytes(filepath);
base64string = Convert.ToBase64String(imageByte);
HttpContext.Session.SetString("Base64Str", base64string);
return new EmptyResult();
}

I suspect the problem might be that, by specifying NVARCHAR (16-byte characters), you're inadvertently "corrupting" the string.
TWO SUGGESTIONS:
Redefine the column as VARCHAR(MAX)
Save a uuencoded string, then read the text back and see if the saved/retrieved string values match.
Look here:
https://dba.stackexchange.com/questions/212160/why-do-i-get-incorrect-characters-when-decoding-a-base64-string-to-nvarchar-in-s
Please post back what you find!
Also - out of curiosity - how are you doing the Base64 encoding in the first place?

I read and write to db but to nText column type with the following just fine: you may convert from vb.net to c# if needed.
#Region "write/read files to db"
Public Function SaveToDB(ByVal fullfilename As String) As String
Dim filedata = Convert.ToBase64String(File.ReadAllBytes(fullfilename))
Return filedata
End Function
Public Function LoadFromDB(ByVal filedata As String, ByVal fullfilename As String) As String
Dim filepath As String = (fullfilename)
File.WriteAllBytes(filepath, Convert.FromBase64String(filedata))
Return filepath
End Function
#End Region
C# version:
class SurroundingClass
{
public string SaveToDB(string fullfilename)
{
var filedata = Convert.ToBase64String(File.ReadAllBytes(fullfilename));
return filedata;
}
public string LoadFromDB(string filedata, string fullfilename)
{
string filepath = (fullfilename);
File.WriteAllBytes(filepath, Convert.FromBase64String(filedata));
return filepath;
}
}

Related

How to convert files to base 64

I am new to C# and I'm really having a trouble on finding a way to convert files(doc, xlsx, jpg, png, etc.) to base64.
So far, what I got is a way to retrieve the path using Directory.GetFiles()....but this is not the result I was expecting.
What I expected it to do is get the data of the files(not the path) and convert it to base64 so that I can display it on my front-end.
Any idea?
Try this:
foreach (string filePath in Directory.GetFiles(#"C:\directory"))
{
Byte[] bytes = File.ReadAllBytes(filePath);
String file = Convert.ToBase64String(bytes);
}

Equivalent of C# Encoding.UTF8.GetBytes in php

I have an example in C# and have to write the same in PHP.
request = request.Replace(sign, string.Empty);
byte[] sha1Request;
using (var shaM = new SHA1Managed())
{
sha1Request = shaM.ComputeHash(Encoding.UTF8.GetBytes(request));
}
log.InfoFormat($"request={request}. sha1Request={Convert.ToBase64String(sha1Request)}. Sign={sign}", request, Convert.ToBase64String(sha1Request));
var pubKey = (RSACryptoServiceProvider)FrontInterface.GetCertificate(checkFrontCertificateCod.Value).PublicKey.Key;
var isValid = pubKey.VerifyData(Encoding.UTF8.GetBytes(Convert.ToBase64String(sha1Request)), new SHA1CryptoServiceProvider(), Convert.FromBase64String(sign));
if (!isValid)
{
throw new Exception("Wrong digital sign");
}
So, I may not convert string to bytes in php and line sha1Request = shaM.ComputeHash(Encoding.UTF8.GetBytes(request));
will be in PHP: sha1Request =sha1(request, true);
Am I rigth? If not, please help me to convert in PHP this line.
Thanks a lot.
Note that sha1 should not really be used any more for security relevant applications, it is out of date.
C# Version:
string text = "<Hällo World>";
byte[] sha1;
using (var shaM = new SHA1Managed())
{
sha1 = shaM.ComputeHash(Encoding.UTF8.GetBytes(text));
}
string encoded = Convert.ToBase64String(sha1);
Console.Write(encoded);
PHP Version:
$text = "<Hällo World>";
// Encode as UTF8 if necessary (May not be necessary if string is already utf-8)
$text = utf8_encode($text);
// Calculate SHA1
$sha1 = sha1($text, TRUE);
// Convert to Base64
$encoded = base64_encode($sha1);
echo($encoded);
Both versions should output
1nSiStZRa/quRru7Sqe+ejupqfs=
Note that the call to utf8_encode should only be there if the string you work with is not actually already encoded in utf8.
If the string is a literal in a *.php file, this depends on how the file is stored on the disk. (What character set it uses).
If the string is retrieved from a web request or from a database or from reading a file, this also depends on what character set the web form, the database or the external file use.

Converting content in a textfile from base64string

i am practicing encryption and decryption.
After i have decrypted some data, i convert the bytes to base64string and store it in a textfile.
After some time i want to decrypt it again, but for that to work i have to convert the content from base64string to bytes again.
I tried with this:
string path = #"C:\encrypt.txt";
string myfile = File.ReadAllText(path);
byte[] convertion = Convert.FromBase64String(myfile);
That will give me an error because the text is actually not a base64string.
Is there anyway to do an convertion?
you can use the following functions for saveing and read base64 strings
public static void WriteAllBase64Text(string path, string text)
{
File.WriteAllText(path, Convert.ToBase64String(Encoding.UTF8.GetBytes(text)));
}
public static string ReadAllBase64Text(string path)
{
var bytes=File.ReadAllText(path);
var encoded = System.Convert.FromBase64String(bytes);
return System.Text.Encoding.UTF8.GetString(encoded);
}

Saving HTML of img/image to Disk

I have a div with an image inside of it. In javascript I am getting the div, and sending the innerHTML of the div to the server. The javascript is oversimplified below:
function uploadImage() {
var imageInfo = document.getElementById('divImage').innerHTML;
PageMethods.uploadImage(imageInfo, onSuccess, onError);
} //end function
I am currently receiving this on the server as a string.
[WebMethod]
public static string uploadImage(string base64FileString){...}
The results are as follows:
<img height="150" width="150" title="name.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...../>
I need to save this image to disk, and I'm at a loss. It's my understanding that I could get everything past the "base64," (using a split) and create an image using the following:
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64FileString);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
image.Save(.....);
But this seems very inefficient. Is there a better way to create the image from the string, a better way to receive the string, or better way to pass the string?
You can use File.WriteAllBytes:
byte[] imageBytes = Convert.FromBase64String(base64FileString);
File.WriteAllBytes(path, imageBytes);
Absolutely no need to go through MemoryStream and the System.Drawing namespace once you have the byte[].
I know there must be a better way to do this, but I have a solution that at least works. If anyone can point out a more sophisticated way I'm all ears. I would have assumed there was some sort of object that would receive the img on the server to save to disk, but maybe not.
Javascript and webmethod remain unchanged. I passed the InnerHTML of the div to the server, and accept it as a string. On the server I used multiple splits (which I understand to be very slow) to get at the base64 part of the image.
[WebMethod]
public static string uploadImage(string base64FileString){
//Get all of the text right of the comma
string base64PartTemp= base64FileString.Split(',')[1];
//The final part of the base64 had a \" to remove
//Now base64PartFinal is the base64 part of the image only
string base64PartFinal= base64PartTemp.Split('\"')[0];
//Get all of the text to the right of the period from original string
string fileTypePart = base64FileString.Split('.')[1];
//Because the file is an image the file type will be 3 chars
string fileType = fileTypePart.Substring(0, 3);
//Use a new guid for the file name, and append the fileType
string finalFileName = Guid.NewGuid() + "." + fileType;
//Turn the final base64 part into byte array
byte[] imageBytes = Convert.FromBase64String(base64PartFinal);
//Get the working directory of the project to store the files
string path= System.AppDomain.CurrentDomain.BaseDirectory.ToString();
//Append that I want to put the image in the images folder, under a designated filename
path += "Images/" + finalFileName;
//Write the image to file
File.WriteAllBytes(path, imageBytes);
...
}
I couldn't find an answer to this for a few days. I hope it helps someone. Like I said, may not be the most efficient solution, but it does work.

Failing to upload Image in base64 bits via XML-RPC [Wordpress/NGG]

I have literally tried every possible way on this but apparently I just can't figure out the right one.
I am trying to upload images to the next-gen gallery that is installed on a wordpress blog. Everything about xml-rpc is working since I am able to do all other stuff with it.
The problem is that server returns an error saying the image is not a valid one. Which is quite obvious that the problem is about base64. However, for test purposes i copied and checked the base64 string and realized it is just right, it converts right to the image using an external base64 to image converter.
This is the line that submits the query.
result = categories.newImage(1, "admin", "password", newImage);
The struct for newImage is;
public struct imageI
{
public string name;
public string type;
public string bits;
public bool overwrite;
public int gallery;
public int image_id;
}
And this is how a new one is initialized, along with converting an image into base64
//Creating the image base64 string
string filename = "asd.jpg";
Image image1 = Image.FromFile(filename);
string base64 = ImageToBase64(image1, image1.RawFormat);
//for test purposes i copied and checked the base64 and it is just right, it converts right to the image using an external base64 to image converter.
Clipboard.SetText(base64);
//Creating a newImage
imageI newImage = default(imageI);
newImage.name = "newImage";
newImage.bits = base64;
newImage.gallery= 86;
And finally my method "ImageToBase64(Image, ImageFomat)";
public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
In case anybody bumps on this, I figured it out, on the line;
newImage.name = "newImage"; the file name should be the same with the one you are uploading, or at least it should have the same extension so that the function in xml-rpc file can resolve the extension and check if it's okay to upload or not.

Categories

Resources