Envoyer des données JSON via POST (ajax) et recevoir une réponse json du contrôleur (MVC)

139

J'ai créé une fonction en javascript comme ça:

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

J'ai appelé le jquery.json-2.3.min.jsfichier de script et je l'ai utilisé pour la toJSON(array)méthode.

Dans le contrôleur, j'ai cette Addaction

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

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

}

Mais sendInfocomme le paramètre de méthode devient nul.

Le modèle:

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

Comment pourrais-je faire une méthode d'action lorsque les données ont été envoyées avec POST?

Je ne sais pas comment m'en servir. De plus, il est possible de renvoyer la réponse (à ajax) via JSON?

Œil de vipère
la source
2
Salut Snake Eyes. Pouvez-vous s'il vous plaît changer la réponse acceptée en réponse de Neha? La réponse de Praveen Prasad est actuellement interrompue car elle (au moment de la rédaction) ne parvient pas à encoder JSON et ne parvient pas à définir l'en-tête JSON Content-Type. Neha fait correctement les deux. J'ai testé les deux réponses.
null

Réponses:

120

Créer un modèle

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

Contrôleurs comme ci-dessous

    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
la source
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) {
                ...
            }
        });

et en action

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

vous pouvez lier votre tableau comme ça

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

j'espère que cela peut vous aider.

Neha
la source
N'est-ce pas ainsi que la stringification du modèle soulève des problèmes de sécurité car on peut falsifier les données et insérer des vulnérabilités XSS?
Dave
@Dave non, un point de terminaison (dans ce cas, une fonction de contrôleur mvc) ne doit JAMAIS faire confiance à un client, donc la vérification XSS doit être effectuée sur le serveur. Le responsable du traitement est responsable de l'analyse correcte des données et de l'envoi des données à l'appelant (webapp). L'appelant pourrait aussi être quelque chose comme un violoniste, un facteur, ou peut-être une autre application .. J'espère que cela a du sens ..
Dieterg
6
Pour info, l'envoi d'un jeu de caractères avec application / json n'est pas valide. Le jeu de caractères s'applique uniquement aux types texte / *. application / json est TOUJOURS UTF-8, quels que soient les en-têtes.
Rich Remer
Lorsque je remplace dataType par contentType dans la requête, cela fonctionne.
huangli
3
Mon problème résolu en utilisant JSON.stringify (), est-ce que quelqu'un peut peu expliquer pourquoi nous en avons besoin alors que quelqu'un envoie un objet json?
Muhammad Zeshan Ghafoor
13

Utilisez JSON.stringify(<data>).

Changez votre code: data: sendInfoen data: JSON.stringify(sendInfo). J'espère que cela peut vous aider.

Hiep Nguyen
la source
1
Vous devrez peut-être définir le contentType sur «application / json» également. Certains points de terminaison peuvent deviner, mais leur dire que c'est JSON est plus fiable.
null
2

Pour publier JSON, vous devrez le stringifier. JSON.stringifyet définissez l' processDataoption sur false.

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

Votre PersonSheets a une propriété int Id, Idn'est pas dans la publication, donc la liaison de modèle échoue. Rendre Id nullable (int?) Ou envoyer au moins Id = 0 avec le POst.

Kirsten
la source
-2

Vous n'avez pas besoin d'appeler $.toJSONet d'ajoutertraditional = true

data: { sendInfo: array },
traditional: true

ferait.

Abdul Munim
la source
pas de bon choix! Si je suis votre code, le paramètre de méthode Add(object[] sendInfo)sera nul!
Snake Eyes