反序列化字典问题

时间:2014-12-12 19:14:46

标签: c# json deserialization json-deserialization

当我反序列化这个对象时,除了图像之外,一切都有效吗?我弄清楚如何获取图像的唯一方法是使用方法' GetImages()'。我想不必使用这个方法,我返回一个Dictionary Key结果。我尝试过多种不同的方式构建对象,但尚未成功找到答案。

这是对象。

public class Item
{
    public int itemId { get; set; }
    public double systemSku { get; set; }
    public int itemECommerceID { get; set; }

    public Dictionary<string, List<Image>> Images { get; set; }
    public Category Category { get; set; }

    public List<Image> GetImages()
    {
        return this.Images["Image"];
    }
}

图片类:

public class Image
{
    public int imageID { get; set; }
    public string description { get; set; }
    public string filename { get; set; }
    public int ordering { get; set; }
    public string publicID { get; set; }
    public string baseImageURL { get; set; }
    public int itemID { get; set; }
    public int itemMatrixID { get; set; }

    public string imageUrl
    {
        get
        {
            return string.Format("{0}{1}.jpg", baseImageURL, publicID);
        }
    }
}

序列化代码摘录:

var stream = await response.Content.ReadAsStreamAsync();
StreamReader reader = new StreamReader(stream);
JavaScriptSerializer js = new JavaScriptSerializer();
var tmpObj = js.Deserialize<dynamic>(reader.ReadToEnd());
TResult obj = js.Deserialize<TResult>(js.Serialize(tmpObj[key]));

2 个答案:

答案 0 :(得分:1)

JSON序列化没有它自己的句柄复杂类型(非字符串,整数等...)字典,你必须创建自己的字典序列化机制或通过{{1}做你正在做的事情}。

在尝试为WCF创建更高效​​的串行器/解串器时遇到了同样的问题,而JSON将更加紧凑,缺少复杂的对象图。

答案 1 :(得分:1)

纯粹作为序列化/反序列化的问题,我能够使用以下Dictionary<string, List<Image>>序列化和反序列化您的JavaScriptConverter

public class JavaScriptImageConverter : JavaScriptConverter
{
    readonly List<Type> Types = new List<Type>();

    const string base64key = "Base64Image";

    public JavaScriptImageConverter() : base()
    {
        Types.Add(typeof(Bitmap)); // Add additional types if required?
        Types.Add(typeof(Image));
    }

    static string ToBase64String(System.Drawing.Image imageIn)
    {
        if (imageIn == null)
            return null;
        ImageConverter converter = new ImageConverter();
        return Convert.ToBase64String((byte[])converter.ConvertTo(imageIn, typeof(byte[])));
    }

    public static Image FromBase64String(string imageString)
    {
        if (string.IsNullOrEmpty(imageString))
            return null;
        ImageConverter converter = new ImageConverter();
        return (Image)converter.ConvertFrom(Convert.FromBase64String(imageString));
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (!typeof(Image).IsAssignableFrom(type))
            return null;
        object obj;
        if (!dictionary.TryGetValue(base64key, out obj))
            return null;
        var str = obj as string;
        if (str == null)
            return null;
        return FromBase64String(str);
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var image = (Image)obj;
        var serialized = new Dictionary<string, object>();
        serialized[base64key] = ToBase64String(image);
        return serialized;
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get {
            return Types;
        }
    }
}

然后使用它:

            var js = new JavaScriptSerializer();

            js.RegisterConverters(new JavaScriptConverter[] { new JavaScriptImageConverter() });
            js.MaxJsonLength = int.MaxValue / 8; // Because my test string turned out to be VERY LONG.

            var imageJson = js.Serialize(item);

            using (var itemBack = js.Deserialize<Item>(imageJson))
            {
                var ok1 = itemBack.Images.SelectMany(p => p.Value).Select(i => i.Width).SequenceEqual(item.Images.SelectMany(p => p.Value).Select(i => i.Width));
                Debug.Assert(ok1); // No assert.
                var ok2 = itemBack.Images.SelectMany(p => p.Value).Select(i => i.Height).SequenceEqual(item.Images.SelectMany(p => p.Value).Select(i => i.Height));
                Debug.Assert(ok2); // No assert.
            }

注意我使用base64字符串比直接使用byte []数组获得更好的序列化/反序列化性能。

(也许这种序列化图像的方式对你的口味来说太不标准了?)