2011-03-21 23 views
10

que tiene este objeto C#:JSON serializar un objeto con parámetros de la función

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

necesito JSON serializar para pasar al navegador de llamada AJAX. Yo uso JavaScriptSerializer, pero serializa a la siguiente JSON:

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

pero lo que necesito es:

{"username":"andrey", "callback": function(self) { return function() {self.doSomething()} (this) }} 
  • sin comillas alrededor de definición de la función.

En este momento, cuando el objeto JSON llega al navegador y se crea, el parámetro 'devolución de llamada' no es una función sino una cadena. ¿Alguna idea de cómo solucionarlo, preferiblemente en el lado del servidor?

+0

[Este post] (http://solutoire.com/2008/06/12/sending-javascript-functions-over-json/) habla de este tema, pero para PHP, pero me Supongo que podrías hacer algo similar en tu caso. –

Respuesta

4

Este comportamiento es deliberado. JSON no debe incluir nada que no sea datos; en su caso, una función ejecutable. El navegador se abrirá a enormes riesgos de seguridad si los datos pueden regresar de un servidor en formato JSON que, cuando se ejecuta, ejecutará funciones arbitrarias (que pueden robar información, redirigir al usuario a un sitio malicioso, etc.)

Las primeras implementaciones de JSON dependen del hecho de que los datos devueltos pueden simplemente ejecutarse a través de eval() para recuperar un objeto. Sin embargo, las personas casi inmediatamente se dieron cuenta de que esto abre enormes riesgos de seguridad y han estado tratando de manejarlo desde entonces. Es por eso que, antes del objeto JSON estandarizado, la gente dejó de poner datos JSON sin procesar en eval() y usó bibliotecas de análisis JSON en su lugar.

El objeto JSON siempre serializará un objeto en solo datos. Esto es por diseño. El formato JSON estandarizado no tiene forma de representar una función ejecutable.

Ahora, puede convertir fácilmente esa devolución de llamada en un navegador en una función pasándola a eval(). Sin embargo, no lo haga. Te estás abriendo para hackear.

En el lado del servidor, los navegadores modernos están diseñados para evitar que esto ocurra exactamente, es decir, los datos que se envían desde un navegador que contiene una función ejecutable.

+0

Sé que eval = evil, pero supongo que tendré que recurrir a él en mi caso.Tengo que pasar ese método js del servidor, así que cualquier forma en que pueda hacerlo está bien. Dudo que suponga un gran riesgo de seguridad ya que siempre es mi servidor el que arroja el método js a la página. – Andrey

+0

En su código de cliente, siempre puede pasar la cadena de código a 'eval (" return "+ code)' y recuperar una función. Sin embargo, por favor ** no lo hagas ** por tu propio bien. Si un pirata informático de alguna manera redirige la url de su cliente a una url maliciosa y devuelve código malicioso en esa JSON, su cliente está realmente jodido. –

+0

¿En qué se diferencia de ese hacker la redirección de las URL del cliente para los archivos de script y la descarga de scripts maliciosos? No estoy discutiendo, solo curiosidad. No soy demasiado fuerte en seguridad. – Andrey

13

Estaba tratando de lograr algo similar. En mi caso estaba usando la sintaxis de MVC Razor tratando de generar un objeto json con una función pasada usando la sintaxis de texto < >.

Pude obtener la salida deseada usando la biblioteca Json.net (usando JsonConvert y JRaw).

Ejemplo:

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

Eso debe conseguir que el objeto JSON con la función (en lugar de la función en una cadena).

la publicación: How to serialize a function to json (using razor @<text>)

Cuestiones relacionadas