Enviar datos JSON a través de POST (ajax) y recibir respuesta json del controlador (MVC)

139

Creé una función en javascript como esa:

function addNewManufacturer() {
       var name = $("#id-manuf-name").val();
       var address = $("#id-manuf-address").val();
       var phone = $("#id-manuf-phone").val();

       var sendInfo = {
           Name: name,
           Address: address,
           Phone: phone
       };

       $.ajax({
           type: "POST",
           url: "/Home/Add",
           dataType: "json",
           success: function (msg) {
               if (msg) {
                   alert("Somebody" + name + " was added in list !");
                   location.reload(true);
               } else {
                   alert("Cannot add to list !");
               }
           },

           data: sendInfo
       });
}

Llamé al jquery.json-2.3.min.jsarchivo de script y lo usé como toJSON(array)método.

En el controlador, tengo esta Addacción

[HttpPost]
public ActionResult Add(PersonSheets sendInfo) {
    bool success = _addSomethingInList.AddNewSomething( sendInfo );

    return this.Json( new {
         msg = success
    });

}

Pero a sendInfomedida que el parámetro método se vuelve nulo.

El modelo:

public struct PersonSheets
{
    public int Id;
    public string Name;
    public string Address;
    public string Phone;
}

public class PersonModel
{
    private List<PersonSheets> _list;
    public PersonModel() {
         _list= GetFakeData();
    }

    public bool AddNewSomething(PersonSheets info) {
         if ( (info as object) == null ) {
            throw new ArgumentException( "Person list cannot be empty", "info" );
         }

         PersonSheets item= new PersonSheets();
         item.Id = GetMaximumIdValueFromList( _list) + 1;
         item.Name = info.Name;
         item.Address = info.Address;
         item.Phone = info.Phone;

         _list.Add(item);

         return true;
    }
}

¿Cómo podría hacerlo en el método de acción cuando los datos se enviaron con POST?

No se como usar. Además, ¿es posible enviar la respuesta (a ajax) a través de JSON?

Ojos de serpiente
fuente
2
Hola ojos de serpiente. ¿Puedes cambiar la respuesta aceptada a la respuesta de Neha? La respuesta de Praveen Prasad está actualmente rota, ya que (al momento de escribir esto) no puede codificar JSON y no puede establecer el encabezado JSON Content-Type. Neha hace correctamente ambas cosas. He probado ambas respuestas.
nulo el

Respuestas:

120

Crear un modelo

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
}

Controladores como abajo

    public ActionResult PersonTest()
    {
        return View();
    }

    [HttpPost]
    public ActionResult PersonSubmit(Vh.Web.Models.Person person)
    {
        System.Threading.Thread.Sleep(2000);  /*simulating slow connection*/

        /*Do something with object person*/


        return Json(new {msg="Successfully added "+person.Name });
    }

Javascript

<script type="text/javascript">
    function send() {
        var person = {
            name: $("#id-name").val(),
            address:$("#id-address").val(),
            phone:$("#id-phone").val()
        }

        $('#target').html('sending..');

        $.ajax({
            url: '/test/PersonSubmit',
            type: 'post',
            dataType: 'json',
            contentType: 'application/json',
            success: function (data) {
                $('#target').html(data.msg);
            },
            data: JSON.stringify(person)
        });
    }
</script>
Praveen Prasad
fuente
141
var SendInfo= { SendInfo: [... your elements ...]};

        $.ajax({
            type: 'post',
            url: 'Your-URI',
            data: JSON.stringify(SendInfo),
            contentType: "application/json; charset=utf-8",
            traditional: true,
            success: function (data) {
                ...
            }
        });

y en acción

public ActionResult AddDomain(IEnumerable<PersonSheets> SendInfo){
...

puedes unir tu matriz de esta manera

var SendInfo = [];

$(this).parents('table').find('input:checked').each(function () {
    var domain = {
        name: $("#id-manuf-name").val(),
        address: $("#id-manuf-address").val(),
        phone: $("#id-manuf-phone").val(),
    }

    SendInfo.push(domain);
});

Espero que esto le pueda ayudar.

Neha
fuente
¿No es así que la identificación en cadena del modelo plantea algunas preocupaciones de seguridad ya que puede alterar los datos e insertar algunas vulnerabilidades XSS?
Dave
@Dave no, un punto final (en este caso una función de controlador mvc) NUNCA debe confiar en un cliente, por lo tanto, la verificación XSS debe realizarse en el servidor. El controlador es responsable de analizar los datos de la manera correcta y enviar los datos nuevamente a la persona que llama (webapp). La persona que llama también podría ser algo así como violinista o cartero, o tal vez otra aplicación ... Espero que esto tenga sentido ...
Dieterg
66
Para su información, el envío de un juego de caracteres con application / json no es válido. El juego de caracteres solo se aplica a los tipos de texto / *. application / json SIEMPRE es UTF-8, independientemente de los encabezados.
Rich Remer
Cuando reemplazo dataType con contentType en la solicitud, funciona.
huangli
3
Mi problema se resolvió usando JSON.stringify (), ¿alguien puede explicar por qué necesitamos esto mientras alguien envía un objeto json?
Muhammad Zeshan Ghafoor
13

Uso JSON.stringify(<data>).

Cambie su código: data: sendInfoa data: JSON.stringify(sendInfo). Espero que esto le pueda ayudar.

Hiep Nguyen
fuente
1
Es posible que también deba establecer contentType en 'application / json'. Algunos puntos finales pueden adivinar, pero decirles que es JSON es más confiable.
nulo
2

Para publicar JSON, tendrá que stringificarlo. JSON.stringifyy establece la processDataopción en falso.

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});
usuario1799669
fuente
0

Your PersonSheets tiene una propiedad int Id, Idno está en la publicación, por lo que falla la vinculación de modelos. Hacer Id nulable (int?) O enviar al menos Id = 0 con el POst.

Kirsten
fuente
-2

No necesita llamar $.toJSONy agregartraditional = true

data: { sendInfo: array },
traditional: true

haría.

Abdul Munim
fuente
no hay buena elección! Si sigo tu código, entonces el parámetro del método Add(object[] sendInfo)será nulo.
Snake Eyes