2013-11-29 1 views
3

Скажем, у меня есть JavaScript Object как:Pass массив объектов, содержащих массивы к действию MVC с помощью JavaScript

function Parent(n, c) { 
    this.Name = n; 
    this.Children = c; 
} 

var p = new Parent("asdf", [1,2,3]); 

И я хочу, чтобы передать массив из parent объекта и его детей к контроллеру MVC 4 через JSON ,

Как я могу отформатировать запрос ajax? Я видел quiteafew по этим линиям, хотя никто из них не использует массив как переменную-член.

Это то, что я до сих пор:

var parents = []; 
parents.push(new Parent("qwer", "child1")); 
parents.push(new Parent("sdfg", 12345)); 
parents.push(new Parent("zxcv", [4,5,6])); 

$.ajax({ 
    url: MakeUrl("Ctlr/Action"), 
    type: "POST", 
    contentType: 'application/json;charset=utf-8', 
    data: JSON.stringify({ 
     parents : parents 
    }), 
    success: function (data, state, xhr) { 
     $("#someDiv").html(data); 
    }, 
    error: function (xhr, state, err) { 
     Utility.displayError(xhr.reponseText); 
    } 
}); 

Результат stringify на самом деле выглядит разумным:

"{"parents":[{"Name":"qwer","Value":"child1"}, {"Name":"sdfg","Value":12345}, {"Name":"zxcv","Value":[4,5,6]}]}" 

Вот Регулятор:

public ActionResult Action(IEnumerable<Parent> parents) { 
    ... 
} 

И в случае, это актуально, серверная сторона Parent объект:

public class Parent { 
    public string Name { get; set; } 
    public object Children { get; set; } 
} 

Children является object, потому что иногда другой тип данных - Я понимаю, что это может быть небольшой код-запах, но конечная функция этого класса передавать произвольные параметры нашей отчетности двигателя.

Простые типы данных, похоже, работают в этом порядке (дата, целое число, строка и т. Д.), Но массив Children просто приходит как {object}, что, насколько я могу судить, это даже не строка, а некоторый общий объект System. Есть ли способ сделать это в MVC, не прибегая к, скажем, подталкивая его в строку и разбирая ее?

+0

Есть ли у вас попробовал 'dynamic' вместо' object'? Проблема здесь в том, что 'object' не по своей сути конвертируется в' IEnumerable'. –

+0

@MichaelPerrenoud Использование 'dynamic' дает такое же поведение. – Hannele

ответ

0

На данный момент я решил предоставить плоский список через javascript, который затем строится на стороне сервера.

Javascript:

var parents = []; 
parents.push(new Parent("asdf", "qwer")); 
parents.push(new Parent("zxcv", 123456)); 

[4,5,].forEach(function (e, i) { 
    params.push(new Parent("Children[" + i + "]", e)); 
}); 

который выглядит после JSON.stringify:

[{"Name":"asdf","Value":"qwer"},{"Name":"zxcv","Value":123456},{"Name":"Children[0]","Value":4},{"Name":"Children[1]","Value":5},{"Name":"Children[2]","Value":6}] 

И затем снимите уплощенная в контроллере с помощью следующей функции:

private IEnumerable<Parent> Unzip(IEnumerable<Parent> parameters) { 
    var unzipped = new Dictionary<string, Parent>(); 
    var r = new Regex(@"(.*)\[.*\]"); 

    foreach (var p in parameters) 
    { 
     var match = r.Match(p.Name.ToString()); 
     if (match.Success) 
     { 
      var name = match.Groups[1].Value; 
      if (!unzipped.ContainsKey(name)) 
       unzipped.Add(name, new Parent() { Name = name, Value = new List<object>() { } }); 

      ((List<object>)(unzipped[name].Value)).Add(p.Value); 
     } 
     else 
      unzipped.Add(p.Name, p); 
    } 

    return unzipped.Values; 
}