Error-invalid length for a base-64 char array - asp.net

I have silverlight app that post some data to another web application ,the data to post is converted to base 64 using code
byte[] byteArray = Encoding.UTF8.GetBytes(sDataToPost);
sDataToPost = Convert.ToBase64String(byteArray);
Another webapplication
get the data using the code
strText = System.Text.Encoding.ASCII.GetString(System.Convert.FromBase64String(postedData));
But it gives the exception invalid length for a base-64 char array
Thanks in Advance
DNM

Depending on how you post the data its quite possible that the Base64 string is being munged a little more. For example URL encoders may do odd things with the + and = symbols in the Base64 string.

Related

Oracle CLOB and NCLOB require even number of bytes

Asp.Net 4, C#, Oracle 11g
Hi, I'm trying to save the content of an html file to an Oracle CLOB column. The html file is uploaded to the server through an asp:Upload button. It is working fine most of the time, the problem is that sometimes the stream at the FileContent property of the button, has an odd number of bytes, and the Write method of the clob column throws an exception, stating that it requires an even number of bytes
How can I solve this problem??? Is there anything I can do to make my html files have an even number of bytes??? Html files are encoded as UTF8, and changing the encoding do modify the number of bytes, but they are still an even number
Thanks in advance
Edit: For now, I'm just increasing the size of the buffer by 1 in the case of the stream length being an odd number, then write the stream, in its own length, to the buffer, thus defaulting the last byte of the buffer. Please advice of any potential errors in doing it this way:
var buffer = new byte[(stream.Length % 2 > 0? stream.Length + 1: stream.Length)];
stream.Read(buffer, 0, (int)stream.Length);
clob.Write(buffer, 0, buffer.Length);
Thanks again
Edit: the previous solution didn't work. The new approach consists of passing the stream to string, add a space at the end of the string, and then convert to stream again. It's working fine until now. Sorry I can't post the code... it's just that I couldn't figured out how to overcome this policy of 4 spaces for code in StackOverflow
I'm assuming that you are using the System.Data.OracleClient classes (as opposed to Oracle's ODP.NET).
The OracleLob class has no method for writing a string, which I would expect for handling CLOBs. Instead, the documentation says:
The .NET Framework Data Provider for Oracle handles all CLOB and NCLOB
data as Unicode. Therefore, when accessing CLOB and NCLOB data types,
you are always dealing with the number of bytes, where each character
is 2 bytes. For example, if a string of text containing three
characters is saved as an NCLOB on an Oracle server where the
character set is 4 bytes per character, and you perform a Write
operation, you specify the length of the string as 6 bytes, although
it is stored as 12 bytes on the server.
In this context, Unicode means the UTF-16 encoding which requires 2 bytes for most characters and 4 or 6 bytes for characters in the supplementary planes.
So if you have a string, you have to convert it to UTF-16 first:
byte[] utf16Bytes = Encoding.Unicode.GetBytes(str);
clob.Write(utf16Bytes, 0, utf16Bytes.Lenght);
Or you can use a StreamWriter to achieve the same:
OracleLob clob = ...
using (StreamWriter writer = new StreamWriter(clob, Encoding.Unicode))
{
writer.Write(str);
}
If your data is in a UTF-8 encoded byte array, then you have to convert it to UTF-16:
byte[] utf8Data = ...
byte[] utf16Data = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, utf8Data);
clob.Write(utf16Data, 0, utf16Data.Length);

iPhone to MS SQL Image Data Type Conversion Question

Alright, here we go!
I am currently developing an iPhone app that will work as a security check-in system for events at a church. The main goal is to be able to search a pre existing MS SQL database for a participant, and then save them to a list on the iPhone/iPod Touch/iPad. Easy enough. One of the fields in the MS SQL database is of Image data type, and its function is to store the participant's image in binary form. I currently am not allowed to switch to varbinary(MAX).
From the iPhone, I use:
UIImage *image = [UIImage imageNamed:#"nameOfImage.jpg"];
NSData *imageData = UIImageJPEGRepresentation(image,1.0);
NSString *imageString = (NSString *)[[[NSString alloc] init] base64StringFromData:(NSData *)imageData];
You may be wondering what the base64StringFromData is. It's a category discussed here, How do I do base64 encoding on iphone-sdk?
In the category, it returns a string as NSASCIIStringEncoding. I then send that string to a Visual Basic web service using POST.
Assume in the following that I have already set up and opened my SQL connection, and initlialized a SQL Data adapter and command. So the function looks similar to this:
Public Function sendCommand(ByVal image As String) As String
Dim commandString As String
commandString = "insert into phoneApp(image) values(#image)"
Dim encoding As New System.Text.UTF8Encoding
sqlDataAdapter.InsertCommand = (commandString, sqlConnection)
sqlDataAdapter.InsertCommand.Parameters.Add(#"image", SqlDbType.Image, image.length).Value = encoding.GetBytes(image)
sqlDataAdapter.ExecuteNonQuery()
End Function
Now, finally, here's what is happening. In another function, I call Response.BinaryWrite(SqlDataReader.Item("image")). In Internet Explorer, doing this would then make the image appear in the browser. Instead, it displays the string in base64 form. Copy and pasting that string in a base64 converter off the net, and it works. So the encoding on the iPhone did encode to base64 properly.
Here's the question. Do I even need to be encoding to base64 to save into Image Data Type, or should I be focusing on learning how to encode the NSData into a different binary string?
I figured it out, and will leave my answer to anyone that stumbles across this. Good luck to you in your programming.
It actually was a lot simpler than I thought. Just use System.Convert to pass in the bytes on the InsertCommand.
sqlDataAdapter.InsertCommand = (commandString, sqlConnection)
sqlDataAdapter.InsertCommand.Parameters.Add(#"image", SqlDbType.Image, image.length).Value = System.Convert.FromBase64String(image)
sqlDataAdapter.ExecuteNonQuery()
In essence, I was getting the bytes for the encoding string but never decoding it further down the line. So I stopped the double encoding by using the Convert before it was inserted into the table.

Accessing the exact data sent using WebClient.UploadData on the server

Newbie question: I'm sending a large text string in the form of a byte array using the WebClient.UploadData method to a web site but I'm not sure exactly where to retrieve that data from on the server. I've read posts that say it is in the request object which I already know but how exactly do I retrieve the specific byte array I sent like in the following c# pseudo code:
byte[] dataSent = request.GettheByteArrayISentFromWebClientUploadDataMethod;
I understand that it may not be as simple as this and that I may need to do some other processing but can anyone post a code snippet that shows how I can get at the byte array that was sent?
Mucho Thank-you
Try reading it from the request stream Request.InputStream:
var bytes = new byte[request.InputStream.Length];
Request.InputStream.Read(bytes, 0, bytes.Length);
If you are sending key/value pairs then you could use the UploadValues method and read them simply as request paraneters:
string value = Request["someKey"];

Place images byte into String is not working?

I tried on Flex 3, facing issue with uploading JPG/PNG image, trace readUTFBytes would return correct bytes length but tmpFileContent is trucated, it would only appear to have upload just 3 characters of data to the server through PHP script which made image unusable. I have no issue for non-images format. What is wrong here?
var tmpFileContent:String = fileRef.data.readUTFBytes(fileRef.data.length);
Is String capable of handle bytes?
I'm not sure what you're looking to do with the image, but you might want to read this:
http://livedocs.adobe.com/flex/3/html/help.html?content=Filesystem_15.html
You may also need a image encoder such as the JPEGEncoder: http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/mx/graphics/codec/JPEGEncoder.html
You could always encode using base64:
var enc:Base64Encoder = new Base64Encoder();
enc.encodeBytes(fileRef.data);
var base64data:String = enc.drain();
The method used in the tutorial is not going to work safely for anything but text files. An arbitrary binary format is likely to contain zeros. A zero (a byte whose value is 0) is generally considered a string terminator in many languages / platforms. This is also the case in Actionscript as this code shows:
var str:String = "abc\x00def";
trace(str);
The string will be truncated to "abc", since 0x00 is considered to mark the end of a string.
I think your best bet is to encode the content to base 64 as maclema suggested. From the php side, decode it back before writting the file with something like:
file_put_contents($myFilePath, base64_decode($fileData["filedata"]));
Also, I can't remember if file_put_contents is binary safe (I think it's not). If that's the case, you should use fopen('you_path',"wb"), fwrite() and fclose() to write the file. Notice the "b" in "wb", which stands for binary. If you don't pass that flag you'll probably have problems with some characters (newline and carriage return, for example).
Added:
Perhaps, following davr suggestion, you could try sending the data ByteArray to see if AMFPHP handles it correctly.
Php does allow embbeded Nuls in strings as this code shows:
$str = "a\x00b";
var_dump(ord($str{0})); // 97
var_dump(ord($str{1})); // 0
var_dump(ord($str{2})); // 98
So, if AMFPHP converts the bytearray to a string and does not mangle it in the process, this could actually work.
// method saves files on the server
function uploadFiles($fileData) {
// new file path an name
// to not overwrite the files we add the microtime before the file name
$myFilePath = '../../_uploads/'.
preg_replace("/[^0-9]+/","_",microtime()).'_'.$fileData["filename"];
// writing on the disk
$fp = fopen($myFilePath,"wb");
if($fp) {
fwrite($fp,$fileData["filedata"]);
fclose($fp);
}
// returning response - is not used anywhere
return true;
}
Otherwise, try echoing var_dump($fileData['filedata']) to see what the actual type AMFPHP is converting the data to (perhaps it uses an array, not sure; given how strings work in php (much like a buffer of single byte characters, though, I think it could be just using strings).

how do i insert html file that have hebrew text and read it back in sql server 2008 using the filestream option?

i am new to the filestream option in sql server 2008,
but i have already understand how to open this option and how to create a table that allow you to save files.
let say my table contains:
id,name, filecontent
i tried to insert an html file (that has hebrew chars/text in it) to this table.
i'm writing in asp.net (c#), using visual studio 2008.
but when i tried to read back the content , hebrew char becomes '?'.
the actions i took were:
1. i read the file like this:
// open the stream reader
System.IO.StreamReader aFile = new StreamReader(FileName, System.Text.UTF8Encoding.UTF8);
// reads the file to the end
stream = aFile.ReadToEnd();
// closes the file
aFile.Close();
return stream; // returns the stream
i inserted the 'stream' to the filecontent column as binary data.
i tried to do a 'select' to this column and the data did return (after i coverted it back to string) but hebrew chars become '?'
how do i solve this problem ?
what I should pay attention to ?
thanks,
gadym
I succeeded to solve this problem.
I was wrong , the problem wasnt in the sql server , but in my code, when i transfer it from binary to string and vice versa.
when you need to convert string (that have hebrew chars) to binary you can write the following lines:
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
//HtmlFile = the file i read as string and now i want to convert it to bytes array.
byte[] ConvertTextToBytesArray = encoding.GetBytes(HtmlFile);
and vice versa :
string str;
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
// result = the binary data i want to convert it back to string
str = enc.GetString(result);
i used for some reason System.Text.ASCIIEncoding instead of System.Text.UTF8Encoding.
thank you Meff !
Looks like the UTF8 encoding may not work with the Hebrew?
See here for an older discussion: http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/73c81574-b434-461f-b766-fb9d0e4353c7
sr = new StreamReader(fs, Encoding.GetEncoding("windows-1255"));
Alternatively, are you sure the file is encoded in UTF8?
Also, FILESTREAM may actually perform worse if the BLOB is under 1MB, and HTML files I would expect to fit that description. Have you considered NVARCHAR(MAX) instead.
http://blogs.msdn.com/manisblog/archive/2007/10/21/filestream-data-type-sql-server-2008.aspx

Resources