Saltar al contenido

¿Cómo pasar datos json POST al método API web como un objeto?

Hacemos una verificación completa cada enunciado de nuestra página web con el objetivo de mostrarte en todo momento la información más veraz y actual.

Solución:

EDITAR : 31/10/2017

El mismo código / enfoque funcionará para Asp.Net Core 2.0 así como. La principal diferencia es que, en el núcleo de asp.net, tanto los controladores web api como los controladores Mvc se fusionan en un modelo de controlador único. Entonces su tipo de retorno podría ser IActionResult o una de sus implementaciones (Ej:OkObjectResult)


Usar

contentType:"application/json"

Necesitas usar JSON.stringify método para convertirlo a JSON string Cuando lo envíes,

Y el enlazador de modelos vinculará los datos json a su objeto de clase.

El siguiente código funcionará bien (probado)

$(function () 
    var customer = contact_name :"Scott",company_name:"HP";
    $.ajax(
        type: "POST",
        data :JSON.stringify(customer),
        url: "api/Customer",
        contentType: "application/json"
    );
);

Resultado

ingrese la descripción de la imagen aquí

contentType La propiedad le dice al servidor que estamos enviando los datos en formato JSON. Dado que enviamos una estructura de datos JSON, la vinculación del modelo se realizará correctamente.

Si inspecciona los encabezados de la solicitud ajax, puede ver que el Content-Type el valor se establece como application/json.

Si no especifica contentType explícitamente, utilizará el tipo de contenido predeterminado que es application/x-www-form-urlencoded;


Edite en noviembre de 2015 para abordar otros posibles problemas planteados en los comentarios

Publicar un objeto complejo

Digamos que tiene una clase de modelo de vista compleja como parámetro del método de acción de la API web como este

public class CreateUserViewModel

   public int Id set;get;
   public string Name set;get;  
   public List Tags set;get;

public class TagViewModel

  public int Id set;get;
  public string Code set;get;

y su punto final de API web es como

public class ProductController : Controller

    [HttpPost]
    public CreateUserViewModel Save([FromBody] CreateUserViewModel m)
    
        // I am just returning the posted model as it is. 
        // You may do other stuff and return different response.
        // Ex : missileService.LaunchMissile(m);
        return m;
    

En el momento de escribir este artículo, ASP.NET MVC 6 es la última versión estable y en MVC6, tanto los controladores de API web como los controladores MVC heredan de Microsoft.AspNet.Mvc.Controller clase base.

Para enviar datos al método desde el lado del cliente, el siguiente código debería funcionar bien

//Build an object which matches the structure of our view model class
var model = 
    Name: "Shyju",
    Id: 123,
    Tags: [ Id: 12, Code: "C" ,  Id: 33, Code: "Swift" ]
;

$.ajax(
    type: "POST",
    data: JSON.stringify(model),
    url: "../product/save",
    contentType: "application/json"
).done(function(res)        
    console.log('res', res);
    // Do something with the result :)
);

El enlace de modelo funciona para algunas propiedades, ¡pero no para todas! Por qué ?

Si no decora el parámetro del método web api con [FromBody] attribute

[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)

    return m;

Y envíe el modelo (objeto javascript sin formato, no en formato JSON) sin especificar el valor de la propiedad contentType

$.ajax(
    type: "POST",
    data: model,
    url: "../product/save"
).done(function (res) 
     console.log('res', res);
);

El enlace de modelo funcionará para las propiedades planas del modelo, no para las propiedades en las que el tipo es complejo / otro tipo. En nuestro caso, Id y Name las propiedades se vincularán correctamente al parámetro m, Pero el Tags La propiedad será una lista vacía.

El mismo problema ocurrirá si está utilizando la versión corta, $.post que utilizará el tipo de contenido predeterminado al enviar la solicitud.

$.post("../product/save", model, function (res) 
    //res contains the markup returned by the partial view
    console.log('res', res);
);

¡Trabajar con POST en webapi puede ser complicado! Me gustaría agregar algo a la respuesta ya correcta.

Se centrará específicamente en POST, ya que tratar con GET es trivial. No creo que muchos busquen resolver un problema con GET con webapis. De todos modos..

Si su pregunta es: en MVC Web Api, cómo: – ¿Usar nombres de métodos de acción personalizados que no sean los verbos HTTP genéricos? – ¿Realizar múltiples publicaciones? – ¿Publicar varios tipos simples? – ¿Publicar tipos complejos a través de jQuery?

Entonces las siguientes soluciones pueden ayudar:

Primero, usar Personalizado Métodos de acción en la API web, agregue una ruta de la API web como:

public static void Register(HttpConfiguration config)

    config.Routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "api/controller/action");

Y luego puede crear métodos de acción como:

[HttpPost]
public string TestMethod([FromBody]string value)

    return "Hello from http post web api controller: " + value;

Ahora, active el siguiente jQuery desde la consola de su navegador

$.ajax(
    type: 'POST',
    url: 'http://localhost:33649/api/TestApi/TestMethod',
    data: '':'hello',
    contentType: 'application/x-www-form-urlencoded',
    dataType: 'json',
    success: function(data) console.log(data) 
);

Segundo, para realizar múltiples publicaciones, Es simple, crea múltiples métodos de acción y decora con el [HttpPost] attrib. Utilizar el [ActionName(“MyAction”)] para asignar nombres personalizados, etc. Llegará a jQuery en el cuarto punto a continuación

En tercer lugar, en primer lugar, publicar varios SENCILLO tipos en una sola acción no es posible. Además, hay una formato especial para publicar incluso un solo tipo simple (además de pasar el parámetro en la consulta string o estilo REST). Este fue el punto que me hizo golpearme la cabeza con Rest Clients (como Fiddler y la extensión de cliente REST avanzada de Chrome) y buscar en la web durante casi 5 horas cuando, finalmente, la siguiente URL resultó ser de ayuda. ¡Citará el contenido relevante para el enlace que podría volverse muerto!

Content-Type: application/x-www-form-urlencoded
in the request header and add a = before the JSON statement:
="Name":"Turbo Tina","Email":"[email protected]
"

PD: Noté el sintaxis peculiar?

http://forums.asp.net/t/1883467.aspx?The+received+value+is+null+ cuando + intento + publicar + en + mi + API + web

De todos modos, superemos esa historia. Hacia adelante:

Cuatro, publicar tipos complejos a través de jQuery, por supuesto, $ .ajax () pronto asumirá el rol:

Digamos que el método de acción acepta un objeto Person que tiene una identificación y un nombre. Entonces, desde javascript:

var person =  PersonId:1, Name:"James" 
$.ajax(
    type: 'POST',
    url: 'http://mydomain/api/TestApi/TestMethod',
    data: JSON.stringify(person),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function(data) console.log(data) 
);

Y la acción se verá así:

[HttpPost]
public string TestMethod(Person person)

    return "Hello from http post web api controller: " + person.Name;

¡Todo lo anterior funcionó para mí! ¡Salud!

Acabo de jugar con esto y descubrí un resultado bastante extraño. Digamos que tiene propiedades públicas en su clase en C # como esta:

public class Customer

    public string contact_name;
    public string company_name;

entonces debes hacer el truco JSON.stringify como lo sugiere Shyju y llamarlo así:

var customer = contact_name :"Scott",company_name:"HP";
$.ajax(
    type: "POST",
    data :JSON.stringify(customer),
    url: "api/Customer",
    contentType: "application/json"
);

Sin embargo, si define getters y setters en su clase de esta manera:

public class Customer

    public string contact_name  get; set; 
    public string company_name  get; set; 

entonces puedes llamarlo mucho más simplemente:

$.ajax(
    type: "POST",
    data :customer,
    url: "api/Customer"
);

Esto usa el encabezado HTTP:

Content-Type:application/x-www-form-urlencoded

No estoy muy seguro de lo que está sucediendo aquí, pero parece un error (¿característica?) En el marco. Es de suponer que los diferentes métodos de enlace están llamando a diferentes “adaptadores”, y mientras que el adaptador para la aplicación / json uno funciona con propiedades públicas, el de los datos codificados por formulario no lo hace.

Sin embargo, no tengo idea de cuál sería la mejor práctica.

Comentarios y valoraciones del post

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *