JavaScriptSerializer с настраиваемым типом
У меня есть функция со списком возвращаемого типа. Я использую это в WebService с поддержкой JSON, например:
[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();
}
это возвращает:
{"d":[{"__type":"Product","Id":"2316","Name":"Big Something ","Price":"3000","Quantity":"5"}]}
Мне тоже нужно использовать этот код в простом aspx файле, поэтому я создал 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();
но он возвращается без типа:
[{"Id":"2316","Name":"Big One ","Price":"3000","Quantity":"5"}]
Кто-нибудь знает, как получить вторую работу Serialization, как первая?
Спасибо!
Ответы
Ответ 1
Хорошо, у меня есть решение, я вручную добавил тип __ в коллекцию в классе 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;
}
}
Есть ли какой-либо "официальный" способ сделать это?:)
Ответ 2
При создании JavaScriptSerializer передайте ему экземпляр SimpleTypeResolver.
new JavaScriptSerializer(new SimpleTypeResolver())
Не нужно создавать свой собственный JavaScriptConverter.
Ответ 3
Основываясь на ответе Джошуа, вам нужно реализовать SimpleTypeResolver
Вот "официальный" способ, который работал у меня.
1) Создайте этот класс
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) Используйте его для сериализации
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) Используйте его для десериализации
System.Web.Script.Serialization.JavaScriptSerializer(new XYZ.Util.ManualResolver());
var result = json.Deserialize<ShoppingCartItem[]>(jsonItemArray);
Полное сообщение здесь: http://www.agilechai.com/content/serialize-and-deserialize-to-json-from-asp-net/