2013-09-23 2 views
2

У меня есть сложный объект JSON, который я хотел бы передать на маршрут контроллера MVC4.AJAX POST Комплекс JSON для контроллера MVC4

{ 
"name": "Test", 
"description": "Description", 
"questions": [ 
    { 
     "id": "1", 
     "type": "1", 
     "text": "123", 
     "answers": [ 
      { 
       "answer": "123", 
       "prerequisite": 0 
      }, 
      { 
       "answer": "123", 
       "prerequisite": 0 
      } 
     ], 
     "children": [ 
      { 
       "id": "2", 
       "type": "2", 
       "text": "234", 
       "answers": [ 
        { 
         "answer": "234", 
         "prerequisite": 0 
        }, 
        { 
         "answer": "234", 
         "prerequisite": 0 
        } 
       ], 
       "children": [] 
      } 
     ] 
    } 
] 

Я эти ViewModels определены:

public class FormDataTransformContainer 
{ 
    public string name { get; set; } 
    public string description { get; set; } 
    public QuestionDataTransformContainer[] questions; 
} 

public class QuestionDataTransformContainer { 
    public int type { get; set; } 
    public string text { get; set; } 
    public AnswerDataTransformContainer[] answers { get; set; } 
    public QuestionDataTransformContainer[] children { get; set; } 
} 

public class AnswerDataTransformContainer { 
    public string answer { get; set; } 
    public int prerequisite { get; set; } 
} 

И это маршрут я удар:

[HttpPost] 
    public ActionResult Create(FormDataTransformContainer formData) 
    { 

В настоящее время, название и описание объекта на FormDataTransformContainer установлены, но массив вопросов равен нулю. Я надеялся, что привязка данных выяснит это, но я предполагаю, что древовидная структура данных немного сложна для этого. Если я правильно понимаю, что является лучшим решением для этого?

+1

Разберите его с помощью библиотеки, например [JSON.NET] (http://json.codeplex.com/) –

+0

Как выглядит ваш контроллер? –

+0

@RobertHarvey, я надеялся, что есть какая-то волшебница DataBinding, которой я отсутствовал, но JSON.NET обеспечивает десериализацию, в которой я нуждаюсь. – mam8cc

ответ

3

questions должно быть свойство, а не поле. Я также изменил бы с массивов на IList<> (предполагая, что ваша библиотека сериализации хорошо справляется), потому что это, вероятно, ближе к тому, что должно быть, и позволяет использовать более общий интерфейс вместо конкретной реализации.

public class FormDataTransformContainer 
{ 
    public string name { get; set; } 
    public string description { get; set; } 
    public IList<QuestionDataTransformContainer> questions { get; set; } 
} 

public class QuestionDataTransformContainer { 
    public int type { get; set; } 
    public string text { get; set; } 
    public IList<AnswerDataTransformContainer> answers { get; set; } 
    public IList<QuestionDataTransformContainer> children { get; set; } 
} 

public class AnswerDataTransformContainer { 
    public string answer { get; set; } 
    public int prerequisite { get; set; } 
} 

Я тестировал эту структуру с Json.net (по умолчанию, по умолчанию, MVC4), и он работает.

+0

Устранение неполадок. Спасибо. – mam8cc

0

Как сказал @ robert-harvey, вы должны использовать библиотеки, такие как JSON.NET, которые уже доступны для тяжелого подъема для вас.

Вытащил из JSON.NET API Docs:
Если вы создаете string json, который держит ваш JSON, вы можете читать из него с new JsonTextReader(new StringReader(json))

0

I аналогичная проблема, решается с помощью следующего кода:

public class ExtendedController : Controller 
{ 
    public T TryCreateModelFromJson<T>(string requestFormKey) 
    { 
     if (!this.Request.Form.AllKeys.Contains(requestFormKey)) 
     { 
      throw new ArgumentException("Request form doesn't contain provided key."); 
     } 

     return 
      JsonConvert.DeserializeObject<T>(
       this.Request.Form[requestFormKey]); 
    } 
} 

и использование:

[HttpPost] 
    [ActionName("EditAjax")] 
    public ActionResult EditAjaxPOST() 
    { 
     try 
     { 
      var viewModel = 
       this.TryCreateModelFromJson<MyModel>(
        "viewModel"); 

      this.EditFromModel(viewModel); 

      return 
       this.JsonResponse(
        this.T("Model updated successfuly."), 
        true); 
     } 
     catch (Exception ex) 
     { 
      this.Logger.Error(ex, "Error while updating model."); 

      return this.JsonResponse(this.T("Error"), false); 
     } 
    } 

Called от JS:

function saveViewModel() { 
    $.post(
     '@Url.Action("EditAjax")', 
     { 
      __RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()', 
      viewModel: ko.mapping.toJSON(viewModel) 
     }, 
     function (data) { 
      // response 
     }); 
} 

Используется дополнительная библиотека для десериализации/сериализации JSON: http://www.nuget.org/packages/Newtonsoft.Json

Смежные вопросы