171

I created a function in javascript like that:

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

I called jquery.json-2.3.min.js script file and I used it for toJSON(array) method.

In controller, I have this Add action

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

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

But sendInfo as method parameter becomes null.

The model:

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

How could I do in action method when the data was sent with POST ?

I don't know how to use. Also, it is possible to send back the response (to ajax) via JSON ?

Asef Hossini
  • 655
  • 8
  • 11
Snake Eyes
  • 16,287
  • 34
  • 113
  • 221
  • 2
    Hi Snake Eyes. Can you please change the accepted answer to Neha's answer? The answer by Praveen Prasad is currently broken as it (at time of writing) fails to encode JSON, and fails to set JSON Content-Type header. Neha's correctly does both of these. I've tested both answers. – null Jan 23 '17 at 10:33

8 Answers8

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

and in action

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

you can bind your array like this

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

hope this can help you.

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
Neha
  • 2,933
  • 3
  • 19
  • 23
  • Isn't it so that stringify'ing the model rises some security concerns as on can tamper the data and insert some XSS vulnerabilities? – Dave May 26 '14 at 11:28
  • @Dave no, an endpoint (in this case an mvc controller function) should NEVER trust a client, therefore the XSS check should be done at the server. The controller is responsible for parsing the data in the correct way and send the data back to the caller (webapp). The caller could also be something like fiddler, or postman, or maybe another app.. Hope this makes sense.. – Dieterg Jul 10 '14 at 09:19
  • 6
    FYI, sending a charset with application/json is invalid. Charset only applies to text/* types. application/json is ALWAYS UTF-8, regardless of any headers. – Rich Remer Sep 26 '14 at 22:50
  • When I replace dataType with contentType in the request, it works. – huangli Apr 06 '16 at 01:50
  • 4
    My problem solved using JSON.stringify(), can anyone little explain why we need this while if someone sending json object? – Muhammad Zeshan Ghafoor Jan 11 '17 at 06:26
  • 2
    @MohammadZeshan Likely because the body, across the wire, would look like `[object]` instead of your string of values. You'd be asking the endpoint, which would likely be C#, to read a JavaScript object. – vapcguy Apr 05 '18 at 23:20
149

Create a model

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

Controllers Like Below

    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>
kah608
  • 545
  • 2
  • 10
Praveen Prasad
  • 31,561
  • 18
  • 73
  • 106
14

Use JSON.stringify(<data>).

Change your code: data: sendInfo to data: JSON.stringify(sendInfo). Hope this can help you.

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
Hiep Nguyen
  • 151
  • 1
  • 2
  • 1
    You may need to set the contentType to 'application/json' as well. Some endpoints may guess, but telling them it is JSON is more reliable. – null Jan 23 '17 at 10:38
9

To post JSON, you will need to stringify it. JSON.stringify and set the processData option to false.

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});
camille
  • 16,432
  • 18
  • 38
  • 60
user1799669
  • 111
  • 1
  • 3
1

Need to use JSON.stringify
And in the Flask use json.loads

res = request.get_data("data")
d_token = json.loads(res)

json.loads returns a dictionary, te values can be retrieved d_token['tokenID']

 $.ajax({
            type: "POST",
            url: "/subscribe",
            contentType: 'application/json;charset=UTF-8',
            data: JSON.stringify({'tokenID':  token}),
            success: function (data) {
                console.log(data);
              
            }
     });

Flask

@app.route('/test', methods=['GET', 'POST'])
def test():
    res = request.get_data("data")
    d_token = json.loads(res)
    logging.info("Test called..{}".format(d_token["tokenID"]))
0

Your PersonSheets has a property int Id, Id isn't in the post, so modelbinding fails. Make Id nullable (int?) or send atleast Id = 0 with the POst .

Kirsten
  • 492
  • 4
  • 11
0
    const URL = "http://localhost:8779/api/v1/account/create";
    let reqObj = {accountName:"", phoneNo:""}

    const httpRequest = new XMLHttpRequest();
    let accountName = document.getElementById("accountName").value
    let phoneNo = document.getElementById("phoneNo").value
    reqObj.accountName = accountName;
    reqObj.phoneNo = phoneNo;
    console.log(reqObj);
    console.log(JSON.stringify(reqObj))
    httpRequest.onload = function() {
        document.getElementById("mylabel").innerHTML = this.responseText;
    }
    httpRequest.open("POST", URL);
    httpRequest.overrideMimeType("application/json");
    httpRequest.send(reqObj);
buddemat
  • 4,552
  • 14
  • 29
  • 49
-2

You don't need to call $.toJSON and add traditional = true

data: { sendInfo: array },
traditional: true

would do.

Abdul Munim
  • 18,869
  • 8
  • 52
  • 61