Estoy tratando de que un método de publicación funcione con angularJS 2 http.

Mi llamada de descanso es la siguiente:

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);
        });
}

El objeto del curso, cuando está en cadena, se ve así:

"{" Título ":" Título de la prueba "," AuthorId ":" scott-allen "," Categoría ":" Arquitectura de software "," CourseLength ":" 2 "," CourseId ":" test-id "}"

He probado tanto la versión en cadena como la no en cadena. Cuando depuro en Chrome, obtengo el siguiente error para ambas versiones:

Respuesta con estado: 0 para URL: nulo

Según tengo entendido, un estado de 0 (cero) significa que nunca llegó al servidor webapi. Tengo CORS habilitado y estoy usando un método similar en una aplicación reactJS de muestra, usando axios y llamando al mismo webapi, y funciona. Instalé la herramienta insomnia json y ejecuté la publicación usando el siguiente formato json y funcionó:

{"CourseId": "steve", "AuthorId": "cory-house", "Título": "Título de la prueba", "CourseLength": "12:40", "Categoría": "Categoría de la prueba"}

No estoy seguro de qué estoy haciendo mal. Mi webapi de asp.net se ve así:

[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();
}

Finalmente, cuando uso Fiddler, veo el siguiente error en la API web:

HTTP / 1.1 400 Tipo de contenido de solicitud incorrecta: application / json; charset = utf-8 Servidor: Kestrel X-Powered-By: ASP.NET Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, X-File- Nombre Access-Control-Allow-Methods: GET, POST Fecha: Dom, 01 de enero de 2017 16:15:15 GMT Duración del contenido: 37

{"": ["Tipo de contenido no admitido ''."]}

He probado muchas configuraciones diferentes del método de publicación en vano. He estado trabajando en esto durante tres días, por lo que se agradece cualquier ayuda.

EDITAR No pude resolver el problema. Mi API web estaba usando el nuevo núcleo asp.net y EF 7. Lo reescribí usando EF 6 y ASP.Net 4.5.2 y funcionó. Sospecho que había algo que me faltaba en mi API web que estaba causando el problema.

0
steveareeno 1 ene. 2017 a las 20:28
Cadena de los datos var body = JSON.stringify(Course) antes de enviar _http.post(url, body, options), verifique que api pueda manejar el tipo de contenido deseado. También elimine el atributo [FromBody]. se utiliza para extraer tipos simples de objetos complejos
 – 
Nkosi
1 ene. 2017 a las 21:21

3 respuestas

Stringifica los datos

var body = JSON.stringify(Course);

Antes de enviar

_http.post(url, body, options)

También elimine el atributo [FromBody]. Se utiliza para extraer tipos simples de objetos complejos.

Referencia: Enlace de parámetros en ASP.NET Web API

La acción terminaría así

[HttpPost]
[Route("CoursesWebApi/api/courses/insert/")]
public IActionResult PostCourse(Course course) { ... }
1
Nkosi 1 ene. 2017 a las 21:41
Perdón. Solo puse eso como ejemplo. Actualicé la publicación a la URL real ...
 – 
steveareeno
1 ene. 2017 a las 21:10

Debe enviar los datos en el cuerpo, ya que su método de API de PostCourse se verá en [FromBody]

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

A continuación se muestra un ejemplo usando 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);
                        });
                }
0
user6801750 1 ene. 2017 a las 21:06

Si ya habilitó CORS en Chrome, intente agregar Access-Control-Allow-Origin, * a sus encabezados. Tuve un problema similar y esto ayuda.

0
Jan Giacomelli 2 ene. 2017 a las 02:14