我需要将javascript对象传递给ASP.NET MVC,我想这样做:
var p = { account:'123', page:'item' };
var message = escape(p.toSource());
// pass message to action method
产生类似这样的东西(未转义为可读性):
({account:"123", page:"item"})
在ASP.NET MVC中,我试图反序列化它并失败。 首先,DataContractJsonSerializer抱怨括号,没问题,在传递之前删除:
{account:"123", page:"item"}
然后它抱怨而不是“,所以我试图使用它来序列化datacontract,并得到:
{"account":"123", "page":"item"}
所以,问题是,我可以在ASP.NET MVC中使用某些东西,它可以使用javascripts toSource格式,还是我从头开始做错了?
答案 0 :(得分:3)
所以,问题是,我可以在ASP.NET MVC中使用某些东西吗? 使用javascripts toSource格式,还是我从头开始做错了?
DataContractJsonSerializer
类在JSON格式方面非常严格,并且符合规范。例如:
{account:"123", page:"item"}
根据规范, 无效的JSON 。您必须在属性名称周围加上双引号。您可以使用JSON.stringify
来生成有效的JSON:
var p = { account:'123', page:'item' };
var message = JSON.stringify(p);
将生成{"account":"123","page":"item"}
,现在是有效的JSON。 JSON.stringify
功能本身内置于现代浏览器中,如果您想支持旧版浏览器,则可以在页面中加入json2.js。
话虽这么说,你可以使用不太严格的JavaScriptSerializer类,或者Json.NET来接受你的无效JSON字符串:
public class MyModel
{
public string Account { get; set; }
public string Page { get; set; }
}
class Program
{
static void Main()
{
var json = "{account:\"123\", page:\"item\"}";
var serializer = new JavaScriptSerializer();
var model = serializer.Deserialize<MyModel>(json);
Console.WriteLine("account = {0}, page = {1}", model.Account, model.Page);
}
}
这就是说我不知道你为什么要手动反序列化JSON而不是依赖内置的JsonValueProviderFactory:
[HttpPost]
public ActionResult MyAction(MyModel model)
{
...
}
并使用AJAX从javascript调用:
$.ajax({
url: '@Url.Action("MyAction", "Home")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ account: "123", page: "item" }),
success: function(result) {
// TODO: process the results
}
});
请注意,现在您现在需要担心任何手动序列化/反序列化。一切都由框架为您处理。
答案 1 :(得分:1)
.toSource()
方法不返回JSON。在您的情况下,对象的有效JSON表示形式为:
{"account": 123, "page": "item"}
.toSource()
返回的格式在MDN documentation中解释。
要在JavaScript中序列化对象,我建议使用第三方库以获得最大的兼容性。具体来说,您可以使用json2.js。但是,如果您使用的是现代浏览器,则还可以使用新JSON object的.stringify()
方法。但是,最通用的方法是第三方库。
答案 2 :(得分:0)
如果有人需要,我就这样做了:
function getSource(o) { var r = [], t; for (var i in o) if (o.hasOwnProperty(i)) { t = i + "~~" + "'" + o[i] + "'"; r.push(t); }; return r.join(); }
请注意,它与原始toSource()有几个限制/差异:
a)我传递的模型总是平坦的,这意味着所有属性都被假定为字符串,如果模型具有复杂属性,则需要更改代码以使用递归来表示复杂属性。
b)我使用单引号,而原始toSource使用双引号
c)我正在将“:”替换为“~~”,因为即使编码它也会破坏网址,因此在服务器端序列化之前,需要进行替换。
d)原始的toSource返回结果,我不需要,所以我的函数返回没有它们的结果。