Question

I'm trying to upload a selected image to Azure Blob from my Android device through

a asp.net WebService I've made.

But I get an orange error in android: "W/System.err(454): SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> Object reference not set to an instance of an object.' faultactor: 'null' detail: org.kxml2.kdom.Node@4205f358 "

I'm not sure if it's my Java code or WebService witch is wrong...

Here is both codes:

WebService:

    [WebMethod]
    public string UploadFile(string myBase64String, string fileName)
    {
        byte[] f = Convert.FromBase64String(myBase64String);

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        // Retrieve a reference to a container. 
        CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");

        // Create the container if it doesn't already exist.
        container.CreateIfNotExists();

        container.SetPermissions(
         new BlobContainerPermissions
         {
             PublicAccess = BlobContainerPublicAccessType.Blob
         });

        // Retrieve reference to a blob named "myblob".
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

        using (MemoryStream stream = new MemoryStream(f))
        {
            blockBlob.UploadFromStream(stream);
        }

        return "OK";
    }

I have tested this code in Forms .net, and it works fine when parsing a Base64 string and converting it to byte[]. So I don't think it's WebService code that's wrong..

Pleas help me!

Here is Java->Android:

private String TAG = "PGGURU";
Uri currImageURI;
    String encodedImage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // To open up a gallery browser
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent, "Select Picture"),1);
}

byte[] b;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

        if (resultCode == RESULT_OK) {

                if (requestCode == 1) {
                        // currImageURI is the global variable I'm using to hold the content:// URI of the image
                        currImageURI = data.getData();
                        String ImageUri = getRealPathFromURI(currImageURI);

                        Bitmap bm = BitmapFactory.decodeFile(ImageUri);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object   
                        b = baos.toByteArray(); 
                            //encoded image to Base64
                        encodedImage = Base64.encodeToString(b, Base64.DEFAULT);

                      //Create instance for AsyncCallWS
                        AsyncCallWS task = new AsyncCallWS();
                        task.execute();
                }
        }
}

public void UploadImage(String image, String imageName) {
    //Create request
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    //Property which holds input parameters
    PropertyInfo PI = new PropertyInfo();
    PI.setName("myBase64String");
    PI.setValue(image);
    PI.setType(String.class);
    request.addProperty(PI);

    PI=new PropertyInfo();
    PI.setName("fileName");
    PI.setValue(imageName);
    PI.setType(String.class);
    request.addProperty(PI);

    //Create envelope
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER11);
    envelope.dotNet = true;
    //Set output SOAP object
    envelope.setOutputSoapObject(request);
    //Create HTTP call object
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

    try {
        //Invole web service
        androidHttpTransport.call(SOAP_ACTION, envelope);
        //Get the response
        SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
        //Assign it to fahren static variable


    } catch (Exception e) {
        e.printStackTrace();
    }
}


private class AsyncCallWS extends AsyncTask<String, Void, Void> {
    @Override
    protected Void doInBackground(String... params) {
        Log.i(TAG, "doInBackground");
        UploadImage(encodedImage, "randomName");
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        Log.i(TAG, "onPostExecute");

    }

    @Override
    protected void onPreExecute() {
        Log.i(TAG, "onPreExecute");

    }

    @Override
    protected void onProgressUpdate(Void... values) {
        Log.i(TAG, "onProgressUpdate");
    }

}

PS: I have granted uses-permission to Internet,WRITE_EXTERNAL_STORAGE and RECORD_AUDIO

Was it helpful?

Solution

Finally I solved the problem :D wihu!

In the WebService I had to change:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
ConfigurationManager.GetSetting("StorageConnectionString"));

to this(almost the same):

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));

and then go to => 'Manage nuget packages' in VS12, and install Windows Azure Storage.

Further more I had to move the variable: byte[] f = Convert.FromBase64String(myBase64String);

outside of the method, like this:

    byte[] f;
    [WebMethod]
    public string UploadFile(string myBase64String, string fileName)
    {
         f = Convert.FromBase64String(myBase64String);
    }

And that was it.

So the WebService look like this:

byte[] f;
    [WebMethod]
    public string UploadFile(string myBase64String, string fileName)
    {
        f = Convert.FromBase64String(myBase64String);


        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        // Retrieve a reference to a container. 
        CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");

        // Create the container if it doesn't already exist.
        container.CreateIfNotExists();

        container.SetPermissions(
         new BlobContainerPermissions
         {
             PublicAccess = BlobContainerPublicAccessType.Blob
         });

        // Retrieve reference to a blob named "myblob".
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

        using (MemoryStream stream = new MemoryStream(f))
        {
            blockBlob.UploadFromStream(stream);
        }
        return "OK";
    }

This will send the image as a ByteArray to the Windows Azure Storage.

Next step is to download the file and convert it to a Bitmap image :)

If this was helpfull please give me some points :D

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top