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);