tickets ticket support create json vb.net asp.net-web-api asp.net-web-api2 http-status-code-415

json - ticket - Error de tipo de medio HTTP 415 no admitido al llamar al punto final de la API web 2



zendesk documentation (3)

Experimenté este problema al llamar a mi punto final de API web y lo resolví.

En mi caso, fue un problema en la forma en que el cliente estaba codificando el contenido del cuerpo. No estaba especificando la codificación o el tipo de medio. Especificándolos se solucionó.

Sin especificar el tipo de codificación , causó error 415:

var content = new StringContent(postData); httpClient.PostAsync(uri, content);

Especificando la codificación y el tipo de medio , éxito:

var content = new StringContent(postData, Encoding.UTF8, "application/json"); httpClient.PostAsync(uri, content);

Tengo un servicio Web API 2 existente y necesito modificar uno de los métodos para tomar un objeto personalizado como otro parámetro, actualmente el método tiene un parámetro que es una cadena simple que proviene de la URL. Después de agregar el objeto personalizado como parámetro, obtengo un error de tipo de medio 415 no admitido al llamar al servicio desde una aplicación de Windows .NET. Curiosamente, puedo llamar a este método con éxito utilizando javascript y el método jquery ajax.

El método de servicio Web API 2 se ve así:

<HttpPost> <HttpGet> <Route("{view}")> Public Function GetResultsWithView(view As String, pPaging As Paging) As HttpResponseMessage Dim resp As New HttpResponseMessage Dim lstrFetchXml As String = String.Empty Dim lstrResults As String = String.Empty Try ''... do some work here to generate xml string for the response ''// write xml results to response resp.Content = New StringContent(lstrResults) resp.Content.Headers.ContentType.MediaType = "text/xml" resp.Headers.Add("Status-Message", "Query executed successfully") resp.StatusCode = HttpStatusCode.OK Catch ex As Exception resp.StatusCode = HttpStatusCode.InternalServerError resp.Headers.Add("Status-Message", String.Format("Error while retrieving results from view {0}: {1}", view, ex.Message)) End Try Return resp End Function

El método permite tanto POST como GET porque el objeto Paging es opcional. Si llamo a este método con una solicitud GET , funciona.

Y el simple código de cliente .NET que llama al servicio se ve así:

Dim uri As String = BASE_URI + "fetch/someview" Dim resp As HttpWebResponse Dim sr As StreamReader Dim lstrResponse As String Dim reqStream As Stream Dim bytData As Byte() Dim req As HttpWebRequest = WebRequest.Create(uri) Dim lstrPagingJSON As String Dim lPaging As New Paging Try lPaging.Page = 1 lPaging.Count = 100 lPaging.PagingCookie = "" req.Method = "POST" lstrPagingJSON = JsonSerializer(Of Paging)(lPaging) bytData = Encoding.UTF8.GetBytes(lstrPagingJSON) req.ContentLength = bytData.Length reqStream = req.GetRequestStream() reqStream.Write(bytData, 0, bytData.Length) reqStream.Close() req.ContentType = "application/json" resp = req.GetResponse() sr = New StreamReader(resp.GetResponseStream, Encoding.UTF8) lstrResponse = sr.ReadToEnd ''// do something with the response here Catch exweb As WebException txtOutput.AppendText("Error during request: " + exweb.Message) Catch ex As Exception txtOutput.AppendText(String.Format("General error during request to {0}: {1}", uri, ex.Message)) End Try

El cliente .NET se está ejecutando en el marco 4.5 y el servicio está en el marco 4.5.2. El error se produce en la línea resp = req.GetResponse() . Algunas cosas que ya probé:

  • en el cliente, establezca el valor req.Accept en "application / xml" o "text / xml"
  • en el método de servicio, se eliminó la línea `resp.Content.Headers.ContentType.MediaType =" text / xml "
  • Reemplace el contenido de la respuesta XML con algún JSON estático. Intentó descartar cualquier problema con el envío de JSON en la solicitud y obtener XML nuevamente en la respuesta.

Hasta ahora sigo recibiendo la misma respuesta de error 415 sin importar lo que intente.

Mencioné que esto funciona cuando se llama desde javascript, aquí está mi llamada ajax que está funcionando:

$.ajax({ headers: {}, url: "api/fetch/someview", type: "POST", data: "{Count:100,Page:1,PagingCookie:/"/"}", contentType: "application/json; charset=utf-8", dataType: "xml", success: function (data) { alert("call succeeded"); }, failure: function (response) { alert("call failed"); } });

En el lado del servicio, no hay nada especial en la configuración de la ruta o cualquier otra cosa, es prácticamente una API web 2 lista para usar. Sé que el enrutamiento está funcionando, las llamadas se están enrutando correctamente al método, no van a otro lugar inesperadamente, así que, ¿qué me falta en el cliente .NET? ¡Cualquier ayuda es muy apreciada!

--- ACTUALIZACIÓN ---
Intenté crear un servicio de API web completamente nuevo para descartar cualquier problema posible con el servicio existente. Creé un controlador con un solo método que toma un objeto personalizado como parámetro. Luego intenté llamar a eso desde el cliente .NET y obtuve el mismo error. También intenté usar WebClient en lugar de HttpWebRequest, pero sigo teniendo el mismo error. Esto también es algo que anteriormente me funcionó con Web API (antes de Web API 2).

--- ACTUALIZACIÓN ---
También intenté crear una nueva aplicación web utilizando la API web 1, cuando llamo eso con un POST mi parámetro de objeto complejo ahora viene en nulo. Tengo otro servicio web que ejecuta Web API 1 y verifiqué que todavía puedo llamar a ese objeto con éxito con objetos complejos. Cualquiera que sea mi problema, parece ser algo con el JSON que pasa entre el cliente y el servidor. He comprobado el JSON. Lo envío y es válido. La definición del objeto también es una coincidencia exacta entre el cliente y el servidor, por lo que el servidor debe poder analizar el JSON.


Tengo el mismo error tuyo. Agrego en el encabezado Content-Type: application / json. Se está ejecutando bien!


Resuelto
Después de golpear mi cabeza contra la pared durante un par de días con este problema, parecía que el problema tenía algo que ver con la negociación del tipo de contenido entre el cliente y el servidor. Investigué más a fondo el uso de Fiddler para verificar los detalles de la solicitud provenientes de la aplicación cliente, aquí hay una captura de pantalla de la solicitud sin procesar tal como fue capturada por el Fiddler:

Lo que obviamente falta es el encabezado Content-Type , aunque lo estaba configurando como se ve en el ejemplo de código en mi publicación original. Pensé que era extraño que el tipo de Content-Type nunca se cumpliera aunque lo estaba configurando, así que eché otro vistazo a mi otro código (de trabajo) que llamaba a un servicio de API web diferente, la única diferencia era que estaba configurando el req.ContentType propiedad antes de escribir al cuerpo de la solicitud en ese caso. Hice ese cambio a este nuevo código y lo hizo, el tipo de Content-Type ahora estaba apareciendo y obtuve la respuesta de éxito esperada del servicio web. El nuevo código de mi cliente .NET ahora se ve así:

req.Method = "POST" req.ContentType = "application/json" lstrPagingJSON = JsonSerializer(Of Paging)(lPaging) bytData = Encoding.UTF8.GetBytes(lstrPagingJSON) req.ContentLength = bytData.Length reqStream = req.GetRequestStream() reqStream.Write(bytData, 0, bytData.Length) reqStream.Close() ''// Content-Type was being set here, causing the problem ''req.ContentType = "application/json"

Eso es todo lo que era, la propiedad ContentType solo tenía que establecerse antes de escribir en el cuerpo de la solicitud

Creo que este comportamiento se debe a que, una vez que el contenido se escribe en el cuerpo, se transmite al punto final del servicio al que se llama, cualquier otro atributo relacionado con la solicitud debe configurarse antes de eso. Por favor corríjame si estoy equivocado o si esto necesita más detalles.