我的控制器中有简单的操作:
[HttpPost]
public JsonResult Action(MenuSet menuSet)
{
//...
}
其中MenuSet
是:
public class MenuSet
{
private IEnumerable<MenuEntry> _menuEntries;
public IEnumerable<MenuEntry> MenuEntries
{
get { return _menuEntries; }
set { _menuEntries = value; }
}
}
public class MenuEntry
{
private string _parentPageName;
private IEnumerable<string> _orderedPages;
public string ParentPageName
{
get { return _parentPageName; }
set { _parentPageName = value; }
}
public IEnumerable<string> OrderedPages
{
get { return _orderedPages; }
set { _orderedPages = value; }
}
}
从客户端,我正在以下面的方式调用此操作:
$.post("Controller/Action",
$.param({ MenuEntries: prepareData() }, true),
null,
"json");
其中prepareData()
函数返回MenuEntries
集合:
function prepareData() {
var menuEntries = new Array();
var menuEntry = {
ParentPageName: null,
OrderedPages: getPagesOrder()
}
menuEntries.push(menuEntry);
return menuEntries;
}
function getPagesOrder() {
var values = new Array();
values.push('samplePageName')
return values;
}
但是JSON对象似乎没有反序列化到服务器端的模型 - 永远不会调用控制器操作。如何使这项工作?
答案 0 :(得分:1)
亚雷克,
如果使用$ ajax而不是$ post,它可以正常工作。我在index.aspx页面上添加了一个按钮,如下所示:
<input type="button" id="btnGo" value="Go" />
另外,添加一个新的javascript文件并将以下内容粘贴到其中(将其保存为/scripts/toJson.js):
//Source: http://www.overset.com/2008/04/11/mark-gibsons-json-jquery-updated/
(function($) {
m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
},
$.toJSON = function(value, whitelist) {
var a, // The array holding the partial texts.
i, // The loop counter.
k, // The member key.
l, // Length.
r = /["\\\x00-\x1f\x7f-\x9f]/g,
v; // The member value.
switch (typeof value) {
case 'string':
return r.test(value) ?
'"' + value.replace(r, function(a) {
var c = m[a];
if (c) {
return c;
}
c = a.charCodeAt();
return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
}) + '"' :
'"' + value + '"';
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
return String(value);
case 'object':
if (!value) {
return 'null';
}
if (typeof value.toJSON === 'function') {
return $.toJSON(value.toJSON());
}
a = [];
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length'))) {
l = value.length;
for (i = 0; i < l; i += 1) {
a.push($.toJSON(value[i], whitelist) || 'null');
}
return '[' + a.join(',') + ']';
}
if (whitelist) {
l = whitelist.length;
for (i = 0; i < l; i += 1) {
k = whitelist[i];
if (typeof k === 'string') {
v = $.toJSON(value[k], whitelist);
if (v) {
a.push($.toJSON(k) + ':' + v);
}
}
}
} else {
for (k in value) {
if (typeof k === 'string') {
v = $.toJSON(value[k], whitelist);
if (v) {
a.push($.toJSON(k) + ':' + v);
}
}
}
}
return '{' + a.join(',') + '}';
}
};
})(jQuery);
在index.aspx中引用此新文件
<script src= "/scripts/toJson.js" type="text/javascript"></script>
并将$ post javascript替换为:
$(document).ready(function() {
$('#btnGo').click(function() {
$.ajax({
type: "POST",
url: '<%=Url.Content("~/Home/Action") %>',
dataType: "json",
data: { MenuEntries: prepareData() },
success: function(msg) {
alert(msg);
},
error: function(xhr) { alert(xhr.statusText); }
});
});
});
function prepareData() {
var menuEntries = new Array();
var menuEntry = {
ParentPageName: "myPageName",
OrderedPages: getPagesOrder()
}
menuEntries.push(menuEntry);
// this serialises the javascript array correctly
return $.toJSON(menuEntries);
}
尝试将操作更改为下面的代码并尝试使用它(这为您提供了两个选项来检查发布的数据):
[HttpPost]
public JsonResult Action(FormCollection formCollection)
{
NameValueCollection test = HttpContext.Request.Form;
// return Json(test[0]);
return Json(formCollection[0]);
}
它在控制器中的“Action”操作中正确反序列化。
试一试。我确定它是“固定的”[edit] - 修复了一半......你需要研究如何玩这个对象。即通过formCollection或通过测试varibale。两者都以不同的形式给对象。!!
答案 1 :(得分:0)
您也可以在操作方法中使用IList<MenuEntry>
作为参数类型。
这两篇博文将帮助您完成 自动模型验证,而其他人的解决方案并非如此。
Asp.net MVC model binding to List<T>
Sending complex JSON objects to Asp.net MVC using jQuery
答案 2 :(得分:0)
您可以使用Phil Haack's
解决方案将json传递给控制器的操作方法。
希望这有帮助!