Tengo una API web .Net Core que devuelve un error de medios no admitidos 415 cuando intento publicar algunos datos que incluyen algunos json. Aquí hay parte de lo que se devuelve en el depurador de Chrome:

Request URL:http://localhost:51608/api/trackAllInOne/set
Request Method:POST
Status Code:415 Unsupported Media Type
Accept:text/javascript, text/html, application/xml, text/xml, */*
Content-Type:application/x-www-form-urlencoded

action:finish
currentSco:CSharp-SSLA:__How_It_Works_SCO
data:{"status":"incomplete","score":""}
activityId:13
studentId:1
timestamp:1519864867900

Creo que esto tiene que ver con que mi controlador no acepte datos application/x-www-form-urlencoded, pero no estoy seguro. Intenté decorar mi controlador con Consumes pero parece que no funciona.

[HttpPost]
[Route("api/trackAllInOne/set")]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Post([FromBody] PlayerPackage playerPackage)
{ etc..}

Cualquier ayuda muy apreciada.

El siguiente código funcionó bien en .Net 4.6.1 y puedo capturar y procesar las publicaciones que se muestran arriba.

[ResponseType(typeof(PlayerPackage))]
public async Task<IHttpActionResult> PostLearningRecord(PlayerPackage playerPackage)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var id = Convert.ToInt32(playerPackage.ActivityId);
        var learningRecord = await _context.LearningRecords.FindAsync(id);
        if (learningRecord == null)
            return NotFound();
etc...
13
Roddy Balkan 1 mar. 2018 a las 04:06

4 respuestas

La mejor respuesta

Para PlayerPackage, la solicitud debe enviar un objeto PlayerPackage Json , según su descripción, no puede controlar la solicitud que se publica desde otro lugar.

Para la solicitud, su tipo es application / x-www-form-urlencoded , enviará datos con {"status": "incomplete", "score": ""} en formato de cadena en lugar del objeto Json. Si desea aceptar {"status": "incomplete", "score": ""} , le sugiero que cambie el método como se muestra a continuación, y luego convierta la cadena a Object por {{X0} }

    [HttpPost]
    [Route("~/api/trackAllInOne/set")]
    [Consumes("application/x-www-form-urlencoded")]
    public IActionResult Post([FromForm] string data)
    {
        PlayerPackage playerPackage = JsonConvert.DeserializeObject<PlayerPackage>(data);
        return Json(data);
    }
28
Edward 2 mar. 2018 a las 05:58

Intente usar [FromForm] en lugar de [FromBody]

public IActionResult Post([FromForm] PlayerPackage playerPackage)

FromBody -> Si vincula desde JSON

FromForm -> Si vincula desde parámetros de formulario

NOTA 1:

También puede eliminar [FromBody] por completo y luego probarlo. Debido a que está esperando que el formulario urlencoded le indique que se una al objeto.

29
Aeseir 2 mar. 2018 a las 08:04

Esto hizo el truco para mí:

[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public IActionResult Post([FromForm]IFormCollection value)

Espero que ayude

2
DanielV 31 ene. 2020 a las 10:11

Yo tuve el mismo problema. FormDataCollection no tiene constructores predeterminados que requieren los formateadores. Use IFormCollection en su lugar

0
jahansha 2 oct. 2018 a las 18:45