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


1

1 Answer 1

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();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.