我有一个复杂的JSON对象,我希望将其传递给MVC4 Controller路由。
{
"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": []
}
]
}
]
我定义了这些ViewModel:
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上的名称和描述属性已设置,但questions数组为null。我希望数据绑定可以解决这个问题,但我认为数据结构的树性质对它来说有点复杂。如果我能纠正什么是最佳解决方案?
答案 0 :(得分: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的默认设置),它可以工作。
答案 1 :(得分:0)
正如@ robert-harvey所说,你应该利用已经可用的JSON.NET等库来为你做繁重的工作。
从JSON.NET API文档中拉出:
如果您创建一个包含json的string json
,则可以使用new JsonTextReader(new StringReader(json))
答案 2 :(得分:0)
我遇到了类似的问题,使用以下代码解决:
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);
}
}
来自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