C# 使用Json.NET序列化XNA矩形
我正在使用 首先看看这个:C# 使用Json.NET序列化XNA矩形,c#,serialization,xna,json.net,C#,Serialization,Xna,Json.net,我正在使用 首先看看这个: using System.Drawing; string json = JsonConvert.SerializeObject(new Rectangle(-3,6,32,32), Formatting.Indented); Console.WriteLine(json); Rectangle deserializedRectangle = JsonConvert.DeserializeObject<Rectangle>(json); 使用系统图; 字符
using System.Drawing;
string json = JsonConvert.SerializeObject(new Rectangle(-3,6,32,32), Formatting.Indented);
Console.WriteLine(json);
Rectangle deserializedRectangle = JsonConvert.DeserializeObject<Rectangle>(json);
使用系统图;
字符串json=JsonConvert.SerializedObject(新矩形(-3,6,32,32),格式化为.Indented);
Console.WriteLine(json);
Rectangle deserializedRectangle=JsonConvert.DeserializeObject(json);
一切正常。控制台输出为:“3,6,32,32”
但是,当我想做同样的事情,我得到一个错误。(刚刚用“使用Microsoft.Xna.Framework;”替换了旧的用法)
控制台输出为:“{X:-3Y:6宽度:32高度:32}”
它抛出的错误是:“将值“{X:-3y:6 Width:32 Height:32}”转换为键入“Microsoft.Xna.Framework.Rectangle”时出错。”
我做了一些检查,这是导致异常的代码:
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);
}
RectangleConverter有一个标记“supportsStringConvert=false”,因此尝试将字符串转换为它将失败
这就是反序列化此特定对象失败的原因。我找到了一种方法,可以让Newtonsoft.Json(Json.Net)很好地处理XNA的
矩形
类。首先,您的矩形应该是类的属性,因此您可以给它一个JsonConverter
属性:
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;
}
}
它可能会得到改进,因此我们非常感谢您的反馈。这是迄今为止我为这个问题找到的最佳解决方案:
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);
}
}
只需将Newtonsoft.JSON配置为使用解析器
var settings = new JsonSerializerSettings() {
ContractResolver = new XnaFriendlyResolver(),
};
var rect = JsonConvert.DeserializeObject<Rectangle>(jsonData, settings);
var settings=new JsonSerializerSettings(){
ContractResolver=新的XnaFriendlyResolver(),
};
var rect=JsonConvert.DeserializeObject(jsonData,设置);
尝试从源代码构建Json.NET,以便查看调试器中引发的异常。#1的答案是:很明显,它使用ToString
方法转换Rectangle
,而不是提取单个成员值,而且没有方法将其转换回。我可能猜Json.NET使用公共get/set属性(如System.Drawing.Rectangle
has),而没有“看到”Microsoft.Xna.Framework.Rectangle
的公共字段。哇,太棒了!谢谢你找到这个。您知道如何解决这个问题,或者如何解决它吗?如果json.net允许,您可以尝试将它序列化为不同的对象(而不是字符串)。我将在明天查看它,就像您需要创建一个简单的DTO来序列化/反序列化XNA矩形结构一样
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);
}
}
var settings = new JsonSerializerSettings() {
ContractResolver = new XnaFriendlyResolver(),
};
var rect = JsonConvert.DeserializeObject<Rectangle>(jsonData, settings);