wenbert
wenbert

Reputation: 5303

Upload an image with Phonegap: InvalidCastException

I am trying to upload a file to my server with Phonegap. I am currently stuck when an error that says:

InvalidCastException
Failed to deserialize WP7CordovaClassLib.Cordova.Commands.FileTransfer+UploadOptions[] with JSON value :: ["{\"filePath\":\"/CapturedImagesCache/PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"server\":\"http://server.myapp.srv.co.nz/pages/fileupload\",\"fileKey\":\"file\",\"fileName\":\"PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"mimeType\":\"image/jpg\",\"params\":\"value1=test&value2=param\",\"chunkedMode\":false}"]

The HTML + Javascript

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="format-detection" content="telephone=no" />
    <title>File Transfer Example</title>

</head>
<body>
    <button id="uploadPhotoButton">Upload a Photo</button>

    <script type="text/javascript" src="cordova-2.2.0.js"></script>
    <script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="js/jquery.mobile-1.2.0.min.js"></script>
    <script type="text/javascript" src="js/camera.js"></script>
    <script type="text/javascript">

    $(document).one("pause", function () {
        console.log('Paused.');
    });

    $(document).one("resume", function () {
        console.log('Resumed.');
    });

    $(document).one("deviceready", function () {
        console.log('Device is ready.');
    });

    $(document).one("backbutton", function () {
        console.log('Back button pressed.');
    });

    $(document).ready(function () {
        console.log('DOM is ready.');

        $(document).on("click", "#uploadPhotoButton", function (e) {
            console.log('clicked button');
            getImage();
        });


        function getImage() {
            // Retrieve image file location from specified source
                navigator.camera.getPicture(uploadPhoto, function (message) {
                    alert('get picture failed');
                }, {
                    quality: 50,
                    destinationType: navigator.camera.DestinationType.FILE_URI,
                    sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
                }
            );

        }

        function uploadPhoto(imageURI) {
            var options = new FileUploadOptions();
            options.fileKey = "file";
            options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
            options.mimeType = "image/jpeg";

            var params = new Object();
            params.value1 = "test";
            params.value2 = "param";

            options.params = params;
            options.chunkedMode = false;

            var ft = new FileTransfer();
            ft.upload(imageURI, "http://my.server.co.nz/pages/fileupload", win, fail, options);
        }

        function win(r) {
            console.log("Code = " + r.responseCode);
            console.log("Response = " + r.response);
            console.log("Sent = " + r.bytesSent);
            alert(r.response);
        }

        function fail(error) {
            alert("An error has occurred: Code = " = error.code);
        }
    });

    </script>
    </body>
</html>

The complete error log.

GapBrowser_Navigated :: /app/www/index.html#/app/www/uploadtest.html
Log:"clicked button"
The thread '<No Name>' (0xf55026a) has exited with code 0 (0x0).
The thread '<No Name>' (0xe3f0326) has exited with code 0 (0x0).
INFO: AppDeactivated
INFO: AppActivated
Log:"Paused."
The thread '<No Name>' (0xf1a02e6) has exited with code 0 (0x0).
Log:"Resumed."
The thread '<No Name>' (0xf2a01d2) has exited with code 0 (0x0).
options = ["{\"filePath\":\"/CapturedImagesCache/PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"server\":\"http://my.server.co.nz/pages/fileupload\",\"fileKey\":\"file\",\"fileName\":\"PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"mimeType\":\"image/jpg\",\"params\":\"value1=test&value2=param\",\"chunkedMode\":false}"]
A first chance exception of type 'System.InvalidCastException' occurred in System.ServiceModel.Web.dll
A first chance exception of type 'System.InvalidCastException' occurred in System.ServiceModel.Web.dll
InvalidCastException
Failed to deserialize WP7CordovaClassLib.Cordova.Commands.FileTransfer+UploadOptions[] with JSON value :: ["{\"filePath\":\"/CapturedImagesCache/PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"server\":\"http://server.myapp.srv.co.nz/pages/fileupload\",\"fileKey\":\"file\",\"fileName\":\"PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"mimeType\":\"image/jpg\",\"params\":\"value1=test&value2=param\",\"chunkedMode\":false}"]
A first chance exception of type 'System.NullReferenceException' occurred in Lion.MyApp.dll
The thread '<No Name>' (0xfdc025e) has exited with code 0 (0x0).
Log:"Error in error callback: FileTransfer1325332352 = ReferenceError: Invalid left-hand side in assignment"
The thread '<No Name>' (0xfa60286) has exited with code 0 (0x0).

Does anyone have an idea on how to make this work?

Thanks!

W

Upvotes: 6

Views: 705

Answers (4)

T.Baba
T.Baba

Reputation: 649

I had this problem before, try to prepare the image in the html first, and dont take it directly from the navigator, it may not saving the taken photo in it cash ;)

In my solution I suppose to have an image tage with id ='camera_image'

img id='camera_image'...

Then i set all the variables of the image in it and I upload it (as you will see in the following code).

here's the 2 functions i used:

function takephoto(){     

      navigator.camera.getPicture(      
        function(uri){
             $('#camera_image').show();
             var img = document.getElementById('camera_image');
             img.style.visibility = "visible"; 
             img.style.display = "block";
             img.src = uri;
             uploadPhoto(img);                    
             alert("Success");
         },
         function(e) {
             console.log("Error getting picture: " + e);
         },
         {
             quality: 50, 
             destinationType: navigator.camera.DestinationType.FILE_URI
         });

        // Get URI of picture to upload 
        var img = document.getElementById('camera_image');
        var imageURI = img.src;
        if (!imageURI || (img.style.display == "none")) {
                alert("Take picture or select picture from library first.");
                return;
        }
}

for choosing an existing photo:

 function choosephoto(){
    navigator.camera.getPicture(
        function(uri) {
            $('#camera_image').show();
            var img = document.getElementById('camera_image');
            img.style.visibility = "visible"; 
            img.style.display = "block";
            img.src = uri;
            uploadPhoto(img);
        },
        function(e) {
            console.log("Error getting picture: " + e);
        },
        {
             quality: 50, 
             destinationType: navigator.camera.DestinationType.FILE_URI, 
             sourceType: navigator.camera.PictureSourceType.SAVEDPHOTOALBUM
        });             

        // Get URI of picture to upload
        var img = document.getElementById('camera_image');
        var imageURI = img.src;
        if (!imageURI || (img.style.display == "none")) {
            alert("please select a pic first");
            return;
        }

  }

in the upload function: function uploadPhoto(img) { imageURI = img.src ...

ps: sorry for the formatting of my code, it doesn't fix well.

Upvotes: 0

Akash Kava
Akash Kava

Reputation: 39916

Put your getImage, uploadImage, win, fail outside of $(document).ready 's inline function call.

Reference to win and fail are actually closure, and phone gap gets it as null when it is trying to access those methods directly. Phonegap is probably expecting a global function instead of hidden function inside a function.

PhoneGap's executes its code out side javascript context, what may work in true javascript fashion may not work correctly with phonegap.

Upvotes: 1

A. Magalh&#227;es
A. Magalh&#227;es

Reputation: 1516

I had a problem similar to yours. I solved this, changing mimeType parameter to 'text/plain'.

Do you use params to send? If it's false I think you need send empty params.

Upvotes: 0

nickaknudson
nickaknudson

Reputation: 4807

I'm thinking that you are malforming your options value. Do you need to pass JSON or an actual object?

Right now you are passing an array with text in it.

options = ["{\"filePath\":\"/CapturedImagesCache/PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"server\":\"http://my.server.co.nz/pages/fileupload\",\"fileKey\":\"file\",\"fileName\":\"PhotoChooser-51766419-c657-46db-a53d-f09bee300a89.jpg\",\"mimeType\":\"image/jpg\",\"params\":\"value1=test&value2=param\",\"chunkedMode\":false}"]

The error seems to involve deserialization issues.

Upvotes: 1

Related Questions