5

I try to consume .net WebAPI with PHP. Everything works fine when there is no error. But when there is some error in WebApi (let say validation of POST data fails) I get the response header easily but I can not find out how to get the response content so I could read what caused the error.

Does some one has idea how to get it or is it impossible?

There is test() action on WebAPI's testController which requires id and text as content of the request or it will return HTTP/1.1 400 Bad Request with content telling the reason.

I use fiddler to test the WebAPI:

POST http://localhost:56018/api/test/test
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:56018
Content-Length: 32
Content: {"id": 5,"text" : '',}

The response is:

HTTP/1.1 400 Bad Request
...
Content-Length: 304

{"args.Text":{"_errors":[{"<Exception>k__BackingField":null,"<ErrorMessage>k__BackingField":"The Text field is required."}],"<Value>k__BackingField":null},"Text":{"_errors":[{"<Exception>k__BackingField":null,"<ErrorMessage>k__BackingField":"The Text field is required."}],"<Value>k__BackingField":null}}

So it's telling in content that "The Text field is required."

Same done with php:

$opts = array('http' =>
    [
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => http_build_query(['id' => 1, 'text' => '']),
        'ignore_errors' => true,
    ]
);
$context  = stream_context_create($opts);
$response = file_get_contents('http://localhost:56018/api/test/test', false, $context);
if($response === false)
{
    echo json_encode($http_response_header);
    die;
}
else
{
    ...
}

So I get the response header data from $http_response_header, but i don't find any way to get the response content I see with Fiddler.

Does some one has idea how to get it or is it impossible?

And finally one tip cURL is not correct answer ;P

Edit: Maybe it's worth to mention what is in $http_response_header in this case when ($response === false):

array (
  0 => 'HTTP/1.1 400 Bad Request',
  1 => 'Cache-Control: no-cache',
  2 => 'Pragma: no-cache',
  3 => 'Content-Type: application/json; charset=utf-8',
  4 => 'Expires: -1',
  5 => 'Server: Microsoft-IIS/10.0',
  6 => 'X-AspNet-Version: 4.0.30319',
  7 => 'X-SourceFiles: =?UTF-8?B?QzpcZG90TmV0NDBcR2FsbGUyV2ViQXBpXEdhbGxlMldlYkFwaVxhcGlcZ2FsbGUyXFRlc3Q=?=',
  8 => 'X-Powered-By: ASP.NET',
  9 => 'Date: Wed, 01 Jun 2016 06:33:11 GMT',
  10 => 'Connection: close',
  11 => 'Content-Length: 304',
)
5
  • php.net/stream_get_meta_data Commented May 31, 2016 at 14:01
  • 1
    The ignore_errors option that you've added to the stream options should take care of this. You're not running a very old version of PHP are you? As in, older than 5.2.10? Commented May 31, 2016 at 14:06
  • I'm running on php 5.5 (sorry the answer took long. I was suppose to come back after while but i forgot) Commented Jun 1, 2016 at 6:16
  • @MarcB Can you explain some more or is this just a random guess? What should i give as an argument for the method? $response equals to false and $http_response_header is header data in array (edited value in to the question). Anyway the name of the method is not promising cause I try to fetch the opposite of meta data which is the content of the response HTTP message. Commented Jun 1, 2016 at 6:56
  • @iainn That the reason I added the ignore_errors line. Doing more debug and it seems that the value was probably overwritten or lost. Now commenting out most of the code around I get the content when using the ignore_error = true; So thanks for pushing me debugging more with that. Commented Jun 1, 2016 at 7:22

2 Answers 2

3

So in the end everything posted here works as it should be. I should have made isolated test case before coming here. (But after debugging while it seems you have tried every option :P)

So I think the 'ignore_errors' => true, line was somehow overwritten or ignored but isolating it form the other code it worked like supposed and the value of $response if the content of the error message.

So in that case you need to do the error checking some other way than if($response === false). Very simple way could be if($http_response_header[0] != 'HTTP/1.1 200 OK') { handle error! }

Thanks for every ones input!

Sign up to request clarification or add additional context in comments.

Comments

2

You can try using curl instead of file_get_contents because curl has better support for error handling:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:56018/api/test/test"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$output = curl_exec($ch);   

$output = json_decode($output);

if(curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) {
  var_dump($output);
}

curl_close($ch);

2 Comments

Yet it was explicitly hinted at not to use cURL : "And finally one tip cURL is not correct answer ;P" ...
Right, searching the answer seems to become to this conclusion. Problem is that it's not in the core of PHP so if you have no control how the PHP is compiled to the server, it might be that there is no cURL library included.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.