2009-06-22 25 views
10

Tengo una función con un tipo de devolución de lista. Estoy usando esto en un servicio web JSON habilitado como:JavaScriptSerializer con tipo personalizado

[WebMethod(EnableSession = true)] 
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
    public List<Product> GetProducts(string dummy) /* without a parameter, it will not go through */ 
    { 
     return new x.GetProducts(); 
    } 

esto devuelve:

{"d":[{"__type":"Product","Id":"2316","Name":"Big Something ","Price":"3000","Quantity":"5"}]} 

necesito utilizar este código en un simple archivo aspx también, así que creé un JavaScriptSerializer:

 JavaScriptSerializer js = new JavaScriptSerializer(); 
     StringBuilder sb = new StringBuilder(); 

     List<Product> products = base.GetProducts(); 
     js.RegisterConverters(new JavaScriptConverter[] { new ProductConverter() }); 
     js.Serialize(products, sb); 

     string _jsonShopbasket = sb.ToString(); 

pero vuelve sin un tipo:

[{"Id":"2316","Name":"Big One ","Price":"3000","Quantity":"5"}] 

¿Alguien tiene alguna idea de cómo conseguir que la segunda serialización funcione como la primera?

Gracias!

Respuesta

3

Ok, tengo la solución, he añadido manualmente el __type a la recogida en el clase JavaScriptConverter.

public class ProductConverter : JavaScriptConverter 
{  public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     Product p = obj as Product; 
     if (p == null) 
     { 
      throw new InvalidOperationException("object must be of the Product type"); 
     } 

     IDictionary<string, object> json = new Dictionary<string, object>(); 
     json.Add("__type", "Product"); 
     json.Add("Id", p.Id); 
     json.Add("Name", p.Name); 
     json.Add("Price", p.Price); 

     return json; 
    } 
} 

¿Hay alguna forma "oficial" para hacer esto? :)

+0

¡guay! me ayuda. Gracias :) –

16

Al crear el JavaScriptSerializer, pasarla a una instancia de SimpleTypeResolver.

new JavaScriptSerializer(new SimpleTypeResolver()) 

No es necesario crear su propio JavaScriptConverter.

+0

gracias, esa es realmente una solución más elegante :) – balint

+0

¿Alguna idea de cómo puedo cambiar el nombre de la propiedad "_type" para eliminar el guión bajo? – reddy

2

Sobre la base de la respuesta de Josué, es necesario implementar un SimpleTypeResolver

Esta es la forma "oficial" que trabajó para mí.

1) Crear esta clase

using System; 
using System.Web; 
using System.Web.Compilation; 
using System.Web.Script.Serialization; 

namespace XYZ.Util 
{ 
    /// <summary> 
    /// as __type is missing ,we need to add this 
    /// </summary> 
    public class ManualResolver : SimpleTypeResolver 
    { 
     public ManualResolver() { } 
     public override Type ResolveType(string id) 
     { 
      return System.Web.Compilation.BuildManager.GetType(id, false); 
     } 
    } 
} 

2) Se usa para serializar

var s = new System.Web.Script.Serialization.JavaScriptSerializer(new XYZ.Util.ManualResolver()); 
string resultJs = s.Serialize(result); 
lblJs.Text = string.Format("<script>var resultObj = {0};</script>", resultJs); 

3) Se usa para deserializar

System.Web.Script.Serialization.JavaScriptSerializer(new XYZ.Util.ManualResolver()); 
var result = json.Deserialize<ShoppingCartItem[]>(jsonItemArray); 

post completo aquí: http://www.agilechai.com/content/serialize-and-deserialize-to-json-from-asp-net/

+0

sharpdeveloper.net está muerto. Es muy molesto y frustrante cuando abordan un problema para tener una respuesta potencialmente dolor de cabeza en un enlace roto. Por favor gente! ¡Solo copia/pega la información aquí! –

+0

@ JayRO-GreyBeard corrigió el enlace – Sameer

Cuestiones relacionadas