0

I try to send an multi-language object to ProductsController, controller accepts the method with no error and object has the correct Id and Tag but the Names and Briefs arrays are empty!

I tried HttpPOST, HttpPUT, HttpOptions but got no success.

JS Code:

    var dataToSend = new FormData();

    var Names = $.makeArray();
    var Briefs = $.makeArray();

    Names.push({ LangCode: 'en', Value: 'TEST' });
    Names.push({ LangCode: 'de', Value: 'TOST' });

    Briefs.push({ LangCode: 'en', Value: 'FOO' });
    Briefs.push({ LangCode: 'de', Value: 'BAR' });

    dataToSend.append("Id", productId);
    dataToSend.append("Tag", "SampleTag");
    dataToSend.append("Names", Names);
    dataToSend.append("Briefs", Briefs);


    $.ajax({
        type: 'PUT',
        contentType: 'application/json; charset=utf-8',
        url: "/api/products/" + productId,
        data: dataToSend,
        processData: false,
        contentType: false,
        success: function (data) {
            DoST();
        },
        error: function (xhr, textStatus, error) {
            var response = JSON.parse(xhr.responseText);
            DoST();
        }
    });

The C# Code is like below: I used LangValue object to pass different language values through the application and It works as expected but not fills via ajax!


    public class LangValue
    {
        public string LangCode { get; set; }
        public string Value { get; set; }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Tag { get; set; }
        public IList<LangValue> Names { get; set; }
        public IList<LangValue> Briefs { get; set; }
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> PutProductLangs(int id, Product product)
    {
        PRODUCT Id and Tag are filled but Names and Briefs arrays are EMPTY!!!
        return NoContent();
    }


Mertez
  • 1,061
  • 3
  • 14
  • 38
  • See if this helps: https://stackoverflow.com/questions/14026539/can-i-append-an-array-to-formdata-in-javascript/25387599 – Mark PM Jan 13 '20 at 11:06

1 Answers1

0

If your using FormData to send the data, you need to .append() each individual name/value to FormData. Since its a collection, you must include the collection indexer (which must be zero based and consecutive),like below :

formData.append("obj[0].Field1", field1Val)
formData.append("obj[0].Field2", field2Val)
 ...
formData.append("obj[1].Field1", field1Val)
formData.append("obj[1].Field2", field2Val)

So update your code to something as shown:

JS

<script>
$("#btn").click(function () {
    function addItems(formdata, Items, name) {
        for (var i = 0; i < Items.length; i++) {
            addSingleItem(formdata, Items[i], name + "[" + i + "]");
        }
    }
    function addSingleItem(formdata, item, name) {
        for (var key in item) {
            formdata.append(name + "." + key,  item[key]);
        }
    }

    var Names = $.makeArray();
    var Briefs = $.makeArray();

    Names.push({ LangCode: 'en', Value: 'TEST' });
    Names.push({ LangCode: 'de', Value: 'TOST' });

    Briefs.push({ LangCode: 'en', Value: 'FOO' });
    Briefs.push({ LangCode: 'de', Value: 'BAR' });

    var formData = new FormData();

    formData.append("Id", productId);
    formData.append("Tag", "SampleTag");
    addItems(formData, Names, "Names");
    addItems(formData, Briefs, "Briefs");


$.ajax({
    type: 'PUT',
    url: "/api/products/" + productId,
    data: formData,
    processData: false,
    contentType: false,
    success: function (data) {
        alert("success!");
    },
    error: function (xhr, textStatus, error) {
        var response = JSON.parse(xhr.responseText);
        alert("error!");
    }
});
});

</script>

Controller

[HttpPut("{id}")]
public async Task<IActionResult> PutProductLangs(int id, [FromForm]Product product)
{
        return NoContent();
}
Xueli Chen
  • 11,987
  • 3
  • 25
  • 36