2011-03-21 49 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>)