cutts
cutts

Reputation: 584

IIS seems to think an Android HttpPost is a GET

UPDATE: These problems were caused by a reverse proxy performing a 301 redirect. Altering the url to the destination of the redirect fixed the issue.

I am struggling to make a POST request from android to a web service.

I have a web service running on IIS7 with the following:

<OperationContract()> _
<Web.WebInvoke(BodyStyle:=WebMessageBodyStyle.Bare, Method:="POST", RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Xml, UriTemplate:="HelloWorld")> _
    Function HelloWorld() As XmlElement 

When I send a POST request to this url from Firefox it works as expected.

When I make the request from an Android device using the following code:

String sRequest = "http://www.myserviceurl.com/mysevice/HelloWorld";
ArrayList<NameValuePair> arrValues = new ArrayList<NameValuePair>();
arrValues.add(new BasicNameValuePair("hello", "world"));

HttpClient httpClient = new DefaultHttpClient();
HttpPost httpRequest = new HttpPost(sRequest);
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setEntity(new UrlEncodedFormEntity(arrValues));
HttpResponse response = httpClient.execute(httpRequest);

I get a Method Not Allowed 405 response and when looking in the IIS logs the request to this url appears as a "GET".

If I change the target of the request to a PHP script that echoes $_SERVER['REQUEST_METHOD'] the output is POST.

The web.config of the web service has GET, HEAD and POST as verbs.

Is there something I have overlooked?

Upvotes: 0

Views: 1057

Answers (2)

grumble
grumble

Reputation: 71

I had to implement a workaround by disabling the automatic redirect and then catching the response code and redirect URL and reexecuting the POST.

// return false so that no automatic redirect occurrs
httpClient.setRedirectHandler(new DefaultRedirectHandler()
{
    @Override
    public boolean isRedirectRequested(HttpResponse response, HttpContext context)
    {
        return false;
    }
});

Then when I issued the request

response = httpClient.execute(httpPost, localContext);
int code = response.getStatusLine().getStatusCode();
// if the server responded to the POST with a redirect, get the URL and reexecute the  POST
if (code == 302 || code == 301)
{
    httpPost.setURI(new URI(response.getHeaders("Location")[0].getValue()));
    response = httpClient.execute(httpPost, localContext);
}

Upvotes: 2

2red13
2red13

Reputation: 11227

try:

DefaultHttpClient http = new DefaultHttpClient();
    HttpResponse res;
    try {
        HttpPost httpost = new HttpPost(s);
        httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.DEFAULT_CONTENT_CHARSET));

        res = http.execute(httpost);


        InputStream is = res.getEntity().getContent();
        BufferedInputStream bis = new BufferedInputStream(is);
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int current = 0;
        while((current = bis.read()) != -1){
              baf.append((byte)current);
         }
        res = null;
        httpost = null;
        String ret = new String(baf.toByteArray(),encoding);
        return  ret;
       } 
    catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        return e.getMessage();
    } 
    catch (IOException e) {
        // TODO Auto-generated catch block
        return e.getMessage();
    }

Upvotes: 0

Related Questions