2011-03-21 64 views
10

对象我有这个C#对象:JSON序列化与功能参数

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'参数不是函数而是字符串。任何想法如何解决它,最好在服务器端?

+0

本帖](http://solutoire.com/2008/06/12/sending-javascript-functions-over-json/)关于这个问题,但为PHP,但我会谈猜你可以在你的情况下做类似的事情。 – 2011-03-21 03:39:15

回答

4

此行为是故意的。 JSON不应该包含任何不是数据的东西 - 在你的情况下是一个可执行的函数。如果数据可以从服务器以JSON格式返回,那么浏览器将面临巨大的安全风险,该服务器在执行时将运行任意函数(可以窃取信息,将用户重定向到恶意站点等)。

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

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

现在,您可以轻松地将浏览器的回调函数转换为函数eval()。但是,不这样做。你只是打开自己的黑客。

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

+0

我知道eval =邪恶,但我想我不得不诉诸于我的情况。我必须从服务器传递这个js方法,所以无论我怎么做都行。我怀疑它带来了巨大的安全风险,因为它始终是我的服务器,将js方法引发到页面。 – Andrey 2011-03-22 02:28:55

+0

在您的客户端代码中,您总是可以将代码字符串传递给'eval(“return”+ code)'并获取一个函数。但是,请**不要为了你自己而做**。如果黑客以某种方式将客户的网址重定向到恶意网址,并且它会以该JSON的形式返回恶意代码,那么您的客户端将遭到严重破坏。 – 2011-03-22 04:34:22

+0

它与那个黑客重定向客户端url的脚本文件和下载恶意脚本有什么不同?我不是在争论,只是好奇 - 我在安全方面并不太强。 – Andrey 2011-03-22 04:46:02

13

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

我能够使用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>)