3

I'm having a problem passing an associative array of objects to MVC Controller. I always get null.

This is what I have on client-side:

function Item() {   
    this.ItemId = GetRandomId('i');
    this.Title = '';
    this.Questions = [];
}

function Question() {
    this.QuestionId = GetRandomId('q');
    this.Description = '';
    this.Values = [];
}

function QuestionValue() {
    this.ValueId = GetRandomId('v');
    this.Description = '';
    this.IsCorrect = false;
}

I have an array 'items' and is filled like this:

items['i123'] = new Item();

On the server-side I mapped that:

public class EvItemJs
{
    public int ItemId { get; set; }
    public string Title { get; set; }
    public EvQuestionJs[] Questions { get; set; }
}

public class EvQuestionJs
{
    public int QuestionId { get; set; }
    public string Description { get; set; }
    public EvQuestionValueJs[] Values { get; set; }
}

public class EvQuestionValueJs
{
    public int ValueId { get; set; }
    public string Description { get; set; }
    public string IsCorrect { get; set; }
}

My MVC Controller method is this:

[HttpPost]
public ActionResult Create(int userId, string userHash, EvItemJs[] items)

On the client-side I call the MVC Controller with this:

var data = { userId: global_data.userId, userHash: global_data.userHash, items: items };

$.ajax({
    url: '/Evaluations/Create',
    type: "POST",
    data: JSON.stringify(data),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    async: true,
    cache: false,
    success: function (msg) {

    },
    error: function (data, ajaxOptions, thrownError) {

    }
});

The userId and userHash parameters have correct values, but the items is always null.

Anyone knows what is wrong? I tried with JSON.stringify and $.toJSON. I remember that sometime I did this with serialization but I cant find it.

Edit: this is what the browser sends to the server:

what the browser sends to the server

MikeSmithDev
  • 15,731
  • 4
  • 58
  • 89
tincho87
  • 349
  • 1
  • 4
  • 12
  • Can you paste the Json for the items that you are using? But I would also try to create an Object on Server Side and try to send a JSON from it and see how it creates that JSON. I will rather use that as a base and try to create using that particular JSON. – Jinal Shah Feb 09 '14 at 14:43
  • 1. Use `Dictionary` instead of `EvItemJs[] items`. 2. You'll have to register a custom Model-Binder for `IDictionary`. – haim770 Feb 09 '14 at 14:47
  • @JinalShah there i posted the Json for the items. – tincho87 Feb 09 '14 at 14:53
  • @haim770 I tried with Dictionary but i only get 2 items with null values. What do you mean with register a custom Model-Binder? – tincho87 Feb 09 '14 at 14:54
  • See https://github.com/counsellorben/ASP.NET-MVC-JsonDictionaryBinding – haim770 Feb 09 '14 at 14:58
  • Can you try to send this json? http://pastebin.com/0RbjqSBG – Jinal Shah Feb 09 '14 at 15:54
  • @haim770 i tried the code, but it works if the items array is a key-value pair. My items array contains objects; you can map it into a dictionary, but i dont have a key-value in my array. I don't know how to map the "index" of the array (ie 'i123') to the key, and the object to the value of the dictionary :s – tincho87 Feb 09 '14 at 19:39
  • @JinalShah i tried it, but if i keep the MVC Controller method to EvItemJs[] it gets null again, but if i change it to object[], i get an array of the "definition of the array", like items[0][0] is a key-value object, with key = "userId" and value "global_data.userId", and no other data. – tincho87 Feb 09 '14 at 19:42
  • The only thing I can say now is you might want to try this http://stackoverflow.com/questions/2246694/how-to-convert-json-object-to-custom-c-sharp-object – Jinal Shah Feb 10 '14 at 01:00

1 Answers1

1

i solved it converting the associative array to non-associative:

function NormalizeItemsArray() {
    var result = new Array();

    for (var i in items) {
        i = items[i];
        var item = new Item();
        item.ItemId = i.ItemId;
        item.Title = i.Title;
        item.Questions = new Array();

        for (var q in i.Questions) {
            q = i.Questions[q];
            var question = new Question();
            question.QuestionId = q.QuestionId;
            question.Description = q.Description;
            question.Values = new Array();

            for (var v in q.Values) {
                v = q.Values[v];
                var questionValue = new QuestionValue();
                questionValue.ValueId = v.ValueId;
                questionValue.Description = v.Description;
                questionValue.IsCorrect = v.IsCorrect;

                question.Values.push(questionValue);
            }
            item.Questions.push(question);
        }
        result.push(item);
    }

    return result;
}

Thanks to everybody!

tincho87
  • 349
  • 1
  • 4
  • 12