I'm using Newtonsoft.Json to deserialize the output from my webservice to an object.
It worked fine until I added a Bitmap
property to my class (named User
) to hold an avatar.
The webservice is returning that propert as a Base64 string, which is as expected.
The problem is when I try to convert back the JSON from the WS to a List<User>
, a JsonSerializationException
is thrown in this block of code:
// T is IList<User>
response.Content.ReadAsStringAsync().Proceed(
(readTask) =>
{
var json = ((Task<string>)readTask).Result;
var result = JsonConvert.DeserializeObject<T>(json); //<-- it fails here
// do stuff!
});
Output from exception is:
Error converting value "System.Drawing.Bitmap" to type 'System.Drawing.Bitmap'. Path '[2].Avatar
and looking at the inner exception:
{"Could not cast or convert from System.String to System.Drawing.Bitmap."}
It's clear that it fails to parse the Base64 string, but it's not clear why.
Any ideas/workaround?
EDIT
I know I can use Convert.FromBase64String
do get a byte array and load a bitmap from that. Then I'd like to update my question to ask about how can I skip or manually parse only that field.
I would like to avoid, having to manually parse all the JSON.
Is this even possible?
EDIT 2
I found out the root problem: JSON is not being correctly serialized in webservice (and I fail to see why). I thought that this was a somewhat different issue, but no. My webservice is simply returning a string "System.Drawing.Bitmap"
instead of its base64 content. Hence the JsonSerializationException
.
I have been unable to solve that issue, the only solution I've found is to turn my field into a byte []
.
Read that field as string,
convert to byte array using Convert.FromBase64String
and
get the image using Bitmap.FromStream(new MemoryStream(bytearray));
EDIT
You can perform image serialization/deserialization with the help of a custom converter
public class AClass
{
public Bitmap image;
public int i;
}
Bitmap bmp = (Bitmap)Bitmap.FromFile(@"......");
var json = JsonConvert.SerializeObject(new AClass() { image = bmp, i = 666 },
new ImageConverter());
var aclass = JsonConvert.DeserializeObject<AClass>(json, new ImageConverter());
This is the ImageConverter
public class ImageConverter : Newtonsoft.Json.JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Bitmap);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var m = new MemoryStream(Convert.FromBase64String((string)reader.Value));
return (Bitmap)Bitmap.FromStream(m);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Bitmap bmp = (Bitmap)value;
MemoryStream m = new MemoryStream();
bmp.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
writer.WriteValue(Convert.ToBase64String(m.ToArray()));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With