3

Spent hours battling simple POST request to a Web API controller.

Here's the response header from Postman:
Access-Control-Allow-Headers → Content-Type
Access-Control-Allow-Methods → GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin → *
Cache-Control → no-cache
Content-Length → 2153
Content-Type → application/json; charset=utf-8
Date → Wed, 04 Nov 2015 23:26:14 GMT
Expires → -1
Pragma → no-cache
Server → Microsoft-IIS/10.0
X-AspNet-Version → 4.0.30319
X-Powered-By → ASP.NET
X-SourceFiles → =?UTF-8?B?QzpcVXNlcnNcSnVsaWFcRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxM1xQcm9qZWN0c1xUd2lsZHlcQVBJXGFwaVxUZXN0XHRlc3Rc?=

I tried both of these POST methods with no success:

  1.         [Route("api/{Test}/test")]
            [HttpPost]
            public void PostByProducts(Test t)
            {
                Console.Write(t.Name);
            }
  2. Update: below is replaced with the code that finally worked. Note, I added Name="PostData" which is the name of the Controller. Otherwise, was getting "null reference" error. "Data data" itself is a class in the Models.

    [ResponseType(typeof(Data))]
    [Route("api/{Test}/testpost/", Name="PostData")]
    public IHttpActionResult PostData(Data data)
    {
        int rValue = 0;
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        else
        {
            if (data != null)
            {
                rValue = repo.PostTestMe(data);
            }
            else
            {
                return BadRequest();
            }
        }

        return CreatedAtRoute("PostData", rValue, data);
    }

On #1 my class "Test" always comes in as null, regardless of the request content-type. I tried them all in Postman, including json. Reading some of the SO answers I did add an empty constructor to the model class ("Test")

On #2 (Old:I get null value when posted from angular) Works from angular now too with the updated code posted here. Works when I post from Postman.

I am at my wits end. All I want to do is to post a simple form from Angular.

Update: Now it works in Postman. I get a non-null value into the function, and get this response in Postman:

Access-Control-Allow-Headers → Content-Type
Access-Control-Allow-Methods → GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin → *
Cache-Control → no-cache
Content-Length → 1308
Content-Type → application/json; charset=utf-8
Date → Thu, 05 Nov 2015 03:15:26 GMT
Expires → -1
Pragma → no-cache
Server → Microsoft-IIS/10.0
X-AspNet-Version → 4.0.30319
X-Powered-By → ASP.NET
X-SourceFiles → =?UTF-8?B?QzpcVXNlcnNcSnVsaWFcRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxM1xQcm9qZWN0c1xUd2lsZHlcQVBJXGFwaVx0ZXN0cG9zdA==?=

Here's what I send in Postman: enter image description here

Angular code: (formdata is straight from the html form, referenced with form.Field1, form.Field2, etc corresponding to the C# model class)

        factory.postForm = function(formdata) {
          return $http({
            url: 'http://domain.com/api/test/testpost',
            data: JSON.stringify(formdata),
            method: 'POST',
            headers: {
              'Content-Type': 'application/json; charset=utf-8'
            }
          }).success(function(response) {
            console.log('posted ' + formdata)
          });
        }

(Old: Still getting null into the API post function.) Everything works fine.

Final update:

In all fairness, when I uploaded my source code to the live server which lives on a shared host, and API is hosted under the same domain, just a different project, everything worked fine, and I got 201 Created OK response.

So, it was a CORS issue, I suppose, which is interesting, because everything works fine on local host for GET requests, but POST gave me hard times.

BTW, I ended up not using [FromBody] - it worked without it.

Update: Ended up adding Name to the route. Everything works.

Florida G.
  • 269
  • 3
  • 11

2 Answers2

0

I have gone through the similar problem earlier and in my case adding [FromBody] before class parameter had solved the problem.

In your case the test method needs to be something like below.

[HttpPost]
public IHttpActionResult PostTest([FromBody]Test test)
{
}

The detailed description for FromUri and FromBody can be found here.

Community
  • 1
  • 1
J-D
  • 1,575
  • 1
  • 11
  • 22
  • Still getting null if posting from angular. Post from Postman works fine. – Florida G. Nov 05 '15 at 17:04
  • I guess somehow Postman avoids the whole CORS thing; maybe it does not run under any web server, even simulated, or maybe it injects itself into the localhost where api runs. – Florida G. Nov 05 '15 at 23:54
0

I have spent hours looking around here in stackoverflow and in google for a solution and here is what I did to solve that

When using HttpClientModule in Angular you do not need to call JSON.stringify(formdata) since the data parameter is stringify as needed

@Injectable()
export class ParkingService {
  constructor(private http: HttpClient) { }

  create(parking: Parking) {
    const requestUrl = environment.apiUrl + 'parking' ;
    const headerOptions = new HttpHeaders();

    headerOptions.set('Content-Type', 'application/json');

    //In this line is my issue
    return this.http.post(requestUrl, JSON.stringify(parking), {headers: headerOptions}) ; 
  }
}

I changed that line to this and it worked (given that it works from postman)

return this.http.post(requestUrl, parking, {headers: headerOptions}) ;

If your angular client is accesing a web api in a differente port/machine you need to enable CORS in that API. For .Net Core here are some good answers How to enable CORS in ASP.net Core WebAPI if its some other programing language look it up in the same way

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99