2011-07-28 53 views
5

ile Dizgeleştirme XNA Dikdörtgen: beklendiği gibiBunda <a href="http://json.codeplex.com/" rel="nofollow">Json.NET</a> İlk göz kullanıyorum 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); 

Her şey çalışır. Konsol çıkışı: "3, 6, 32, 32"

Ama aynı şeyi the XNA Rectangle ile yapmak istediğimde bir hata alıyorum. "{X: -3 Hasılat: 6 genişliği: 32 Yükseklik: 32}"

ve konsol çıkış

("kullanılarak Microsoft.Xna.Framework" sadece bununla kullanarak eski yerine) hatayı atar: "Microsoft.Xna.Framework.Rectangle" yazmak için "{X: -3 Y: 6 Genişlik: 32 Yükseklik: 32}" değeri dönüştürülürken hata oluştu. "

  1. neden oluyor?

  2. Neler yanlış gidiyor ve bunu nasıl düzeltirim?

    Biraz araştırma yaptık
+0

böylece kaynağından Json.NET bina deneyin çözümleyicinizi kullanmak Newtonsoft.JSON yapılandırmak Hata ayıklayıcısına atılan istisnayı görebilirsiniz.# 1'in cevabı: "Rectangle" in "ToString" yöntemini, tek tek üye değerlerini ayıklamak yerine dönüştürdüğü oldukça açıktır ve geri dönüştürmek için bir yöntem yoktur. Json.NET'in genel get/set özelliklerini (System.Drawing.Rectangle' gibi) kullandığını ve Microsoft.Xna.Framework.Rectangle'nun public * alanlarını * görmediğini tahmin edebilirim. –

cevap

5

, bu duruma neden olur kod şudur:

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

bu tip bir çevirici bulamıyor dönüştürme çalışır temsilciye fiili çağrı. Bu durumun nedenini araştırmak, serileştirici diğer türleri doğru bir şekilde serileştirebilmekte ve seri hale getirebilmektedir.

DÜZENLEME:

Bu XNA Dikdörtgen tip olarak tanımlanır çünkü çalışmaz:

[Serializable] 
    [TypeConverter(typeof(RectangleConverter))] 
    public struct Rectangle : IEquatable<Rectangle> 

Json.NET TypeConverter türünü alır ve üzerine bu yöntemi çağırır:

TypeConverter fromConverter = GetConverter(targetType); 

    if (fromConverter != null && fromConverter.CanConvertFrom(initialType)) 
    { 
     // deserialize 
    } 

RectangleConverter, "supportedStringConvert = false" yazan bir bayrağı vardır, böylece bir dizeyi dönüştürmeyi denemek başarısız olur.

Bu belirli nesnenin seri hale getirilmesinin başarısız olmasının nedeni budur.

+0

Vay, harika iş! Bunu bulduğunuz için teşekkürler. Sorunun nasıl giderileceği veya çevresinde nasıl çalışılacağı hakkında bir fikriniz var mı? – riki

+0

Eğer json.net buna izin veriyorsa, onu farklı bir nesneye (string değil) serileştirmeye çalışabilirsiniz. Yarın kontrol edeceğim –

+0

XNA Dikdörtgen yapısını serileştirmek/serpiştirmek için basit bir DTO oluşturmanız gerekecek gibi görünüyor – MattDavey

2

Newtonsoft.Json (Json.Net) 'i XNA'nın Rectangle sınıfında güzel oynamak için bir yol buldum.

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

Muhtemelen geri besleme takdir böylece geliştirilebilir: Ona bir JsonConverter niteliğini verebilir böylece Öncelikle, dikdörtgen bir sınıfın bir özellik olmalıdır.

0

Bu kadar bu soruna yönelik bulduğum en iyi çözümdür:

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

Ve sadece

var settings = new JsonSerializerSettings() { 
    ContractResolver = new XnaFriendlyResolver(), 
}; 

var rect = JsonConvert.DeserializeObject<Rectangle>(jsonData, settings); 
İlgili konular