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

C# JSON使用函数参数序列化对象,c#,ajax,json,javascriptserializer,C#,Ajax,Json,Javascriptserializer,我有一个C#对象: 我需要对其进行JSON序列化,以便在ajax调用中传递给浏览器。我使用JavascriptSerializer,但它序列化为以下JSON: {"username":"andrey", "callback": "function(self) { return function() {self.doSomething()} (this) }"} 但我需要的是: {"username":"andrey", "callback": function(self) { return f

我有一个C#对象:

我需要对其进行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”参数不是一个函数,而是一个字符串。你知道如何修复它吗,最好是在服务器端?

这种行为是故意的。JSON不应该包含任何非数据的内容——在您的例子中是一个可执行函数。如果数据能够以JSON格式从服务器返回,那么浏览器将面临巨大的安全风险,该服务器在执行时将运行任意功能(可以窃取信息、将用户重定向到恶意站点等)

JSON的早期实现依赖于这样一个事实,即返回的数据可以通过eval()简单地执行以返回对象。然而,人们几乎立刻意识到这会带来巨大的安全风险,并一直在努力应对。这就是为什么在标准化JSON对象出现之前,人们不再将原始JSON数据放入eval()中,而是使用JSON解析库

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

现在,您可以通过将浏览器上的回调传递给eval()轻松地将其转换为函数。但是,不要这样做。你只是在为黑客行为敞开心扉


在服务器端,现代浏览器的设计是为了防止这种情况发生,即从包含可执行功能的浏览器发送数据。

我正试图实现类似的功能。 在我的例子中,我使用MVC Razor语法试图生成一个json对象,并使用@syntax传递一个函数

我能够使用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对象(而不是字符串中的函数)

职位:

您可以使用函数对象的构造函数。看

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

通过这种方式,您可以在后台数据库中获得函数实现的详细信息,而不是在源代码中进行硬编码

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);

谈到这个问题,但对于PHP,但我想你可以在你的情况下做类似的事情。我知道eval=evil,但我想我必须在我的情况下求助于它。我必须从服务器上传递js方法,所以不管我用什么方法都可以。我怀疑这会带来巨大的安全风险,因为总是我的服务器将js方法抛出页面。在你的客户端代码中,你总是可以将代码字符串传递到
eval(“return”+code)
,然后返回一个函数。但是,请不要为了你自己而这样做。如果黑客以某种方式将您的客户端url重定向到恶意url,并在该JSON中返回恶意代码,您的客户端将彻底崩溃。这与黑客重定向客户端url以获取脚本文件并下载恶意脚本有何不同?我不是在争论,只是好奇——我对安全性不是太强。黑客甚至不需要重定向客户端的url。例如,从服务器到客户端的数据可能会通过多层代理和其他过滤器。其中一个可能被黑客入侵。黑客获取你的数据,丢弃你的回调文本字符串,并用他自己的恶意代码替换,然后将其发送给你的客户端。您的客户端将执行该恶意代码。现在,如果只是数据,至少客户端不会执行您自己没有编写的任何代码;你的程序只会看到奇怪的数据。我想我必须再看看我的架构。谢谢,我会考虑你的建议[不要做]
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);