2

I am attempting to call a put method on my server using OkHttp from an Android application.

This is the api method signature:

public void Put(int userId, string regId)
{
}

This is the Android code to call the above method:

private boolean SendGCMRegIdToServer(String registrationId, Integer userId) throws IOException {
    HttpUrl url = new HttpUrl.Builder()
            .scheme("http")
            .host(serverApiHost)
            .addPathSegment("AppDashboard")
            .addPathSegment("api")
            .addPathSegment("GCM/")
            .build();

    MediaType JSON
            = MediaType.parse("application/json; charset=utf-8");

    String json = "{'userId':" + userId + ","
            + "'regId':'" + registrationId + "'"
            + "}";

    RequestBody requestBody = RequestBody.create(JSON, json);

    Request request = new Request.Builder()
            .url(url)
            .put(requestBody)
            .build();

    //this should post the data to my server
    Response response = client.newCall(request).execute();
    if(response.code() == 400)
        return false;

    return true;
}

Now the problem is I am getting the error code 405 in the response saying Method not allowed, but I cannot see where the problem is because I can successfully call the method using Postman on the server itself as below:

http://localhost/AppDashboard/api/GCM?userId=5&regId=123

I'm thinking it may have something to do with an integer or string being passed incorrectly in the JSON string, but cannot see why this isn't working.

halfer
  • 19,824
  • 17
  • 99
  • 186
jjharrison
  • 841
  • 4
  • 19
  • 33

3 Answers3

1

I see two different approaches in your REST api calls. In the one of OkHttp you send a PUT method with a JSON object serialized, and in POSTMAN you send a PUT (although I guess you do a GET) request with the parameters within the URL, I mean not in JSON body structure.

Anyway, HTTP 405 is telling you that your backend does not support the PUT method, and probably it's expecting a POST method with the "X-HTTP-Method-Override:PUT" HTTP header since POST is more standard method in REST than PUT.

What would I do is check your POSTMAN request carefully and adjust the one of Android to be the same method, parameters and headers, not more.

Answer Update (as question has been updated)

Of course there is a problem with that verb, as I said above IIS handles only the standard methods and PUT is not one of those. You have three choices:

  1. Change your PUT to POST.
  2. Use POST with X-HTTP-Method-Override to PUT. (reference)
  3. Modify IIS config to support non standard REST methods. I personally wouldn't suggest the 3rd one, since it's attached to the backend config (e.g. imagine you change IIS to NancyFX).
GoRoS
  • 5,183
  • 2
  • 43
  • 66
  • So is there a way of sending an Okhttp put request without a body but with url parameters instead... – jjharrison Feb 05 '16 at 19:56
  • Sure, but why would you do that? I recommend to use JSON as everybody does. However, if you want to do that and use form parameters, adjust your MediaType and do something like this: https://github.com/square/okhttp/wiki/Recipes#posting-form-parameters – GoRoS Feb 05 '16 at 19:59
1

i had the same problem and server was returning 405 . after some search i realized that is a configuration problem on IIS that does not let put requests. so there is no problem in android code and you should config your server to let this kind of requests. see this , this and this

Community
  • 1
  • 1
ReZa
  • 1,273
  • 2
  • 18
  • 33
1

Ok thanks for replies guys but seems I was getting a little confused between the two methods I was using to pass the params to my API.

Here's what I did:

changed the signature of the method to post with a param [FromBody] as a Model (only supports one paramater)...

public void Post([FromBody]UserGcmRegIdModel model)
{
}

I was then able to change my method call to the following using a nicer JSONBuilder and using .post in the request builder rather than .put

JSONObject jsonObject = new JSONObject();

    try {
        jsonObject.put("UserId", userId);
        jsonObject.put("RegId", registrationId);
    } catch (JSONException e) {
        e.printStackTrace();
    }

    String json = jsonObject.toString();

    RequestBody requestBody = RequestBody.create(JSON, json);

    Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();

I still don't know if there is a problem with put() methods on IIS but using a post in my case was absolutely fine so I'm going with that...

jjharrison
  • 841
  • 4
  • 19
  • 33