1
votes

I am creating an Android app that uploads basic text files to a user's onedrive by using the Microsoft Graph API.

I have discovered by using https://developer.microsoft.com/en-us/graph/graph-explorer to create files using a PUT request with the link "https://graph.microsoft.com/v1.0/me/drive/root:/Test.txt:/children", With the header "Content-Type" "text/plain", and filling the request body with the text to go into the text file. Using the graph explorer, this works without any issues, however when testing my code with all of these things, it always gives me an error 400.

public void saveOpportunityToServer (final String textToSave, String fileName)
    {
        try
        {
            StringRequest request = new StringRequest(Request.Method.PUT, "https://graph.microsoft.com/v1.0/me/drive/root:/" + fileName + ":/content",
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response)
                        {
                            Log.d ("PAST QUOTES SAVE", "Created file on server");
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error)
                        {
                            Log.e ("PAST QUOTES SAVE", "Failed to create file on server: " + error.toString());
                        }
                    })
            {
                @Override
                public byte[] getBody() throws AuthFailureError {
                    return textToSave.getBytes();
                }

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    HashMap<String, String> headers = new HashMap<String, String>();
                    headers.put ("Authorization", "Bearer " + mAccessToken);
                    headers.put ("Content-Type", "text/plain");
                    return headers;
                }
            };


            serverRequest.getInstance().addToRequestQueue(request, "Create past quote file request");

        }catch (Exception e){
            Log.e ("PAST QUOTES SAVE", "Failed to create file on server");
        }
    }

Where serverRequest is an instance of Volley.RequestQueue.

If the function "getBody()" in String Request is left untouched, or the "textToSave" string is empty, the server responds with a success, creates the requested file, but as expected, the file is empty.

Does anyone have a solution, or at least a reason for why the plain text isn't being accepted?

Edit: Request & Response Headers and Body

Headers:

"Authorization" "Bearer [AccessToken]"

"Content-Type" "text/plain"

Body: "This is a test"

I'm certain the authorization is working, but I guess there is a chance that the server is not properly interpreting the content-type header, however it works on the mentioned website, so I am not sure why it wouldn't in my program.

The response is an empty Error 400, which is stated as a Malformed Request by Microsoft, which leads me to believe the above, however I cant see a way to fix it.

1
Can you update your question to include the response headers and body? They generally include extra information about the failure which can be of useBrad
@Brad The question has been edited to include them explicitlyLeone Shamoth

1 Answers

0
votes

Finally, I found where the issue is.

Due to how volley works, you cannot simply add a "Content-Type" header to the "getHeaders()" function. To change the body content type, you must override a separate function, "geyBodyContentType()"

Here is my final request code, for anyone wondering in the future how to solve this problem.

StringRequest request = new StringRequest(Request.Method.PUT, "https://graph.microsoft.com/v1.0/me/drive/root:/ " + fileName + ":/content",
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response)
                        {
                            Log.d ("PAST QUOTES SAVE", "Created file on server");
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error)
                        {
                            Log.e ("PAST QUOTES SAVE", "Failed to create file on server: " + error.toString());
                        }
                    })
            {
                @Override
                public byte[] getBody() throws AuthFailureError {
                    return textToSave.getBytes();
                }

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    HashMap<String, String> headers = new HashMap<String, String>();
                    headers.put ("Authorization", "Bearer " + mAccessToken);
                    return headers;
                }

                @Override
                public String getBodyContentType ()
                {
                    return ("text/plain");
                }
            };