I\'m using Json.NET First look at this:
using System.Drawing;
string json = JsonConvert.SerializeObject(new Rectangle(-3,6,32,32), Formatting.Indented);
Con
I've done some checking, this is the code that causes the exception:
public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
{
return MiscellaneousUtils.TryAction<object>(delegate { return Convert(initialValue, culture, targetType); }, out convertedValue);
}
The actual call to the delegate that does the Convert work cannot find a convertor for this type. Investigating the cause for this, as the serializer is able to serialize and deserialize other types correctly.
EDIT:
This does not work, since the XNA Rectangle type is defined as:
[Serializable]
[TypeConverter(typeof(RectangleConverter))]
public struct Rectangle : IEquatable<Rectangle>
Json.NET retrieves TypeConverter type, and calls this method on it:
TypeConverter fromConverter = GetConverter(targetType);
if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
{
// deserialize
}
The RectangleConverter has a flag saying "supportsStringConvert = false", so attempting to convert a string into it fails.
This is the reason that deserializing this specific object is failing.
This is by far the best solution I've found for this issue:
private class XnaFriendlyResolver : DefaultContractResolver {
protected override JsonContract CreateContract(Type objectType) {
// Add additional types here such as Vector2/3 etc.
if (objectType == typeof(Rectangle)) {
return CreateObjectContract(objectType);
}
return base.CreateContract(objectType);
}
}
And just configure Newtonsoft.JSON to use the resolver
var settings = new JsonSerializerSettings() {
ContractResolver = new XnaFriendlyResolver(),
};
var rect = JsonConvert.DeserializeObject<Rectangle>(jsonData, settings);
I figured out a way to get Newtonsoft.Json (Json.Net) to play nice with XNA's Rectangle
class. First, your rectangle should be a property of a class so you can give it a JsonConverter
attribute:
public class Sprite
{
[JsonConverter(typeof(MyRectangleConverter))]
public Rectangle Rectangle;
}
public class MyRectangleConverter : JsonConverter
{
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
var rectangle = (Rectangle)value;
var x = rectangle.X;
var y = rectangle.Y;
var width = rectangle.Width;
var height = rectangle.Height;
var o = JObject.FromObject( new { x, y, width, height } );
o.WriteTo( writer );
}
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
var o = JObject.Load( reader );
var x = GetTokenValue( o, "x" ) ?? 0;
var y = GetTokenValue( o, "y" ) ?? 0;
var width = GetTokenValue( o, "width" ) ?? 0;
var height = GetTokenValue( o, "height" ) ?? 0;
return new Rectangle( x, y, width, height );
}
public override bool CanConvert( Type objectType )
{
throw new NotImplementedException();
}
private static int? GetTokenValue( JObject o, string tokenName )
{
JToken t;
return o.TryGetValue( tokenName, StringComparison.InvariantCultureIgnoreCase, out t ) ? (int)t : (int?)null;
}
}
It could probably be improved so feedback is appreciated.