为什么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格式工作,还是我从头开始做错了?

为什么DataContractJsonSerializer和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返回闭包的结果,这是我不需要的,所以我的函数返回结果没有他们。