Search code examples
jquery.netajaxrestcordova

jQuery ajax post of jpg image to .net webservice. Image results corrupted


I have a phonegap jQuery app that opens the camera and take a picture.

I then POST this picture to a .net webservice, which I've coded.

I can't use phonegap FileTransfer because such isn't supported by Bada os, which is a requirement.

I've successfully loaded the image from phonegap FileSystem API, I've attached it into an .ajax type:post, I've even received it from .net side, but when .net save the image into the server, the image results corrupted

->> It is a correct Base64 encoded file but there is this header "data:image/jpeg;base64,/9j/4AAQ.....="

How do I get rid of this header? should I trim it from .net or from ajax?

Any help will be appreciated.

This is my code:

//PHONEGAP CAMERA ACCESS (summed up)
navigator.camera.getPicture(onGetPictureSuccess, onGetPictureFail, { quality: 50, destinationType:Camera.DestinationType.FILE_URI });
window.resolveLocalFileSystemURI(imageURI, onResolveFileSystemURISuccess, onResolveFileSystemURIError);
fileEntry.file(gotFileSuccess, gotFileError);
new FileReader().readAsDataURL(file);


//UPLOAD FILE
function onDataReadSuccess(evt) {
        var image_data = evt.target.result;
        var filename = unique_id();
        var filext = "jpg";
                
         $.ajax({
                type : 'POST',
                url : SERVICE_BASE_URL+"/fotos/"+filename+"?ext="+filext,   
                cache: false, 
                timeout: 100000, 
                processData: false, 
                data: image_data, 
                contentType: 'image/jpeg',
                success : function(data) {
                       
                            console.log("Data Uploaded with success. Message: "+ data);
                            $.mobile.hidePageLoadingMsg();
                            $.mobile.changePage("ok.html");
                       }
                       });
            }

On my .net Web Service this is the method that gets invoked:

public string FotoSave(string filename, string extension, Stream fileContent)
{
   string filePath = HttpContext.Current.Server.MapPath("~/foto_data/") + "\\" + filename;
   FileStream writeStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
   int Length = 256;
   Byte[] buffer = new Byte[Length];
   int bytesRead = readStream.Read(buffer, 0, Length);
   // write the required bytes
   while (bytesRead > 0)
   {
      writeStream.Write(buffer, 0, bytesRead);
      bytesRead = readStream.Read(buffer, 0, Length);
   }
   readStream.Close();
   writeStream.Close();
 }

Solution

  • Ok, I got it working. The problem is that when we use $.ajax() the result is something that has to fit as text into html, so for example you can put it directly into a tag

    <textarea> background-image: data:data:image/jpeg;base64,/9j/4AAQ.....=</textarea>
    

    But when you try to Convert.FromBase64String(thestring) even .net tells you that "invalid character in Base64 string".

    In conclusion, leaving $.ajax as it is, I've modified my .net function this way:

     //Convert input stream into string
     StreamReader postReader = new StreamReader(inputStreamFromWebService);
     string base64String = postReader.ReadToEnd();
     if (base64String.StartsWith("data:"))
     {
                //remove unwanted ajax header
                int indexOfBase64String = base64String.IndexOf(",") + 1;
                int lenghtOfBase64String = base64String.Length - indexOfBase64String;
                base64String = base64String.Substring(indexOfBase64String, lenghtOfBase64String);
      }
    
      //Convert from base64 string to byte[]
      byte[] byteFromString;
      byteFromString = Convert.FromBase64String(base64String);
      MemoryStream stream = new MemoryStream(byteFromString);
    
      System.IO.FileStream outFile;
      outFile = new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
      outFile.Write(byteFromString, 0, byteFromString.Length);
      outFile.Close();