JSON使用函数参数序列化对象

时间:2011-03-21 03:29:57

标签: c# ajax json javascriptserializer

我有这个C#对象:

var obj = new {
    username = "andrey",
    callback = "function(self) { return function() {self.doSomething()} (this) }"
}

我需要JSON序列化它以在ajax调用中传递给浏览器。我使用JavascriptSerializer,但它序列化为以下JSON:

{"username":"andrey", "callback": "function(self) { return function() {self.doSomething()} (this) }"}

但我需要的是:

{"username":"andrey", "callback": function(self) { return function() {self.doSomething()} (this) }}
  • 没有功能定义的引号。

现在,当JSON对象到达浏览器并创建时,'callback'参数不是函数而是字符串。知道如何修复它,最好是在服务器端吗?

3 个答案:

答案 0 :(得分:20)

我试图完成类似的事情。 在我的情况下,我使用MVC Razor语法尝试生成一个json对象,其中使用@< text>传入的函数。句法。

我能够使用Json.net库(使用JsonConvert和JRaw)获得所需的输出。

示例:

// set the property value using JRaw
var obj = new {
    username = "andrey",
    callback = new JRaw("function(self) { return function() {self.doSomething()} (this) }")
}
// and then serialize using the JsonConvert class
var jsonObj = JsonConvert.SerializeObject(obj);

那应该使用函数(而不是字符串中的函数)来获取json对象。

发表: How to serialize a function to json (using razor @<text>)

答案 1 :(得分:7)

这种行为是故意的。 JSON不应包含任何非数据 - 在您的情况下是可执行函数。如果数据可以从JSON格式的服务器返回,浏览器将面临巨大的安全风险,当执行时,将运行任意功能(可以窃取信息,将用户重定向到恶意网站等)。

JSON的早期实现依赖于以下事实:返回的数据可以通过eval()简单地执行以获取对象。然而,人们几乎立即意识到这会带来巨大的安全风险,并一直试图处理它。这就是为什么在标准化的JSON对象之前,人们停止将原始JSON数据放入eval()并改为使用JSON解析库。

JSON对象始终将对象序列化为仅数据。这是设计的。标准化的JSON格式无法表示可执行函数。

现在,您可以轻松地将浏览器上的回调转换为函数,方法是将其传递给eval()。但是,不要这样做。你只是为了黑客攻打自己。

在服务器端,现代浏览器旨在防止发生这种事情 - 即从包含可执行功能的浏览器发送数据。

答案 2 :(得分:0)

您可以使用Function对象的构造函数。参见https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Function

在json中,将callback属性设置为描述Function构造函数参数的字符串数组。然后,当json数据到达客户端时,您必须将Array转换为Function对象的实例。

这样,您可以在后台数据库中获得函数实现的详细信息,而不必在源代码中进行硬编码。

const json = '{"username":"andrey","callback":["self","return self.doSomething()"]}';

//Parse the json to an object
const object = JSON.parse(json);

//Convert the callback property from Array to Function
object["callback"] = new Function(...object["callback"]);

//Create a parameter for calling the Function
var self = {
    doSomething() {
        console.log("Do something called");
    }
}

//Call the function
object["callback"](self);