为什么DataContractJsonSerializer和toSource产生不同的结果
本文关键字:结果 DataContractJsonSerializer toSource 为什么 | 更新日期: 2023-09-27 18:11:11
我需要将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"}
然后它抱怨一个而不是",所以我试着用它来序列化数据合约,得到:
{"account":"123", "page":"item"}
所以,问题是,我可以在ASP中使用一些东西。. NET MVC,这将与javascripts toSource格式工作,还是我从头开始做错了?
所以,问题是,我可以在ASP中使用一些东西。NET MVC,那就行了用javascript 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
}
});
看,现在你不再需要担心任何手动序列化/反序列化。
.toSource()
方法不返回JSON。在您的示例中,对象的有效JSON表示将是:
{"account": 123, "page": "item"}
.toSource()
返回的格式在MDN文档中有解释。
要在JavaScript中序列化对象,我建议使用第三方库以获得最大的兼容性。具体来说,您可以使用json2.js。但是,如果使用的是现代浏览器,也可以使用新JSON对象的.stringify()
方法。但是,最通用的方法还是第三方库。
以防有人需要,我已经这样做了:
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)我将":"替换为"~~",因为即使编码它也会破坏url,所以在服务器端序列化之前,你需要做替换。
d)原始toSource返回闭包的结果,这是我不需要的,所以我的函数返回结果没有他们。