steveareeno
steveareeno

Reputation: 1977

angular 2 http post method failing

I am trying to get a post method working with angularJS 2 http.

My rest call is as follows:

saveCourse(Course: any) {
    let url ='https://server/CoursesWebApi/api/courses/insert';
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    let options = new RequestOptions({ headers: headers});
    return this._http.post(url, { data: Course }, options)
        .toPromise()
        .then(res => res.json().data)
        .catch((err: any) => {
            console.log(err);
            return Promise.reject(err);
        });
}

The course object, when stringified, looks like this:

"{"Title":"Test title","AuthorId":"scott-allen","Category":"Software Architecture","CourseLength":"2","CourseId":"test-id"}"

I have tried both the stringified and non-stringified version. When I debug in chrome, I get the following error for both versions:

Response with status: 0 for URL: null

As I understand it, a status of 0 (zero) means it never even made it to the webapi server. I have CORS enabled and I am using a similar method in a sample reactJS app, using axios and calling the same webapi, and it works. I installed the insomnia json tool and executed the post using the following json format and it worked:

{ "CourseId": "steve", "AuthorId": "cory-house", "Title": "Test Title", "CourseLength": "12:40", "Category": "Test Category" }

I am not sure what I am doing wrong. My asp.net webapi looks like this:

[HttpPost]
[Route("CoursesWebApi/api/courses/insert/")]
public IActionResult PostCourse([FromBody] Course course)
{
    if (!ModelState.IsValid)
    {
        return HttpBadRequest(ModelState);
    }

    _context.Course.Add(course);
    try
    {
        _context.SaveChanges();
    }
    catch (DbUpdateException)
    {
        if (CourseExists(course.CourseId))
        {
            return new HttpStatusCodeResult(StatusCodes.Status409Conflict);
        }
        else
        {
            throw;
        }
    }

    return Ok();
}

Finally, when I use fiddler I see the following error on the web api:

HTTP/1.1 400 Bad Request Content-Type: application/json; charset=utf-8 Server: Kestrel X-Powered-By: ASP.NET Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, X-File-Name Access-Control-Allow-Methods: GET, POST Date: Sun, 01 Jan 2017 16:15:15 GMT Content-Length: 37

{"":["Unsupported content type ''."]}

I have tried many different configurations of the post method to no avail. Been working on this for three days so any help is appreciated.

EDIT I wasn't able to resolve the issue. My web api was using the new asp.net core and EF 7. I rewrote it using EF 6 and ASP.Net 4.5.2 and it worked. I suspect there was something I was missing in my web api that was causing the issue.

Upvotes: 0

Views: 4168

Answers (3)

Jan Giacomelli
Jan Giacomelli

Reputation: 1339

If you already enabled CORS in chrome try to add Access-Control-Allow-Origin, * to your headers. Had similar problem and this helps.

Upvotes: 0

Nkosi
Nkosi

Reputation: 247008

Stringify the data

var body = JSON.stringify(Course);

before sending

_http.post(url, body, options)

Also remove [FromBody] attribute. It is used to extract simple types from complex objects.

Reference: Parameter Binding in ASP.NET Web API

The action would end up like this

[HttpPost]
[Route("CoursesWebApi/api/courses/insert/")]
public IActionResult PostCourse(Course course) { ... }

Upvotes: 1

user6801750
user6801750

Reputation: 242

You need to send the data in body as your PostCourse api method will look in [FromBody]

            //public IActionResult PostCourse([FromBody] Course course)

Below is an example using Observable:

            public saveCourse(Course: any): Observable<Course> {
                    let url ='https://server/CoursesWebApi/api/courses/insert';
                    let body: string = JSON.stringify(Course);
                    let  headers = new Headers();
                    let headers.append('Content-Type', 'application/json');
                    let options = new RequestOptions({ headers: this.headers });

                    return this.authHttp.put(this.url, body,options)
                        .map((res: Response) => {
                                    return res;
                                })
                            .catch((error: any) => {
                                // Error on post request.
                                return Observable.throw(error);
                        });
                }

Upvotes: 0

Related Questions