2012-11-07 7 views
5

Przy projekcie, nad którym pracuję, zaczęliśmy używać biblioteki Json.Net.Json.net luźna kontra deserializacja typu surowego

Jednak właśnie się dowiedziałem, że json.net jest "luźny" na typie łańcucha.

Oto przykład:

DTO klasa

[JsonObject] 
public class DTO 
{ 
    [JsonProperty] 
    public string type; 
} 

deserializacji

byte[] rawBody = GetBytes(@"{""type"":true}"); 
using (MemoryStream ms = new MemoryStream(rawBody)) 
{ 
    using (StreamReader sr = new StreamReader(ms)) 
    { 
     var serializer = new JsonSerializer(); 

     return serializer.Deserialize(sr, typeof(DTO)); 
    } 
} 

To będzie deserializować 'typem' atrybutów jak "True". Jednak oczekiwałbym, że to się nie powiedzie i wyrzuci wyjątek, ponieważ istnieje niedopasowanie typu. Robi to samo, jeśli zastąpię true przez 1 w jsonie. Właściwością "typ" właściwości będzie "1".

pytania:

  1. Czy istnieje sposób, aby wymusić ścisłe serializacji?

  2. Czy istnieją inne typy niż ciąg, które mają domyślną konwersję, tak jak to, co tu widzimy?

Dziękuję.

JF

Odpowiedz

1

wymyśliłem obejście.

Mimo że działa, nie wiem, czy to jest dobry sposób na rozwiązanie mojego "problemu".

użyłem konwertery przekonwertować z

Oto co zrobiłem:

[JsonObject] 
public class DTO 
{ 
    [JsonProperty] 
    public string type; 
} 

Zwyczaj konwerter:

class JsonStrictConverter<T> : JsonConverter 
    { 
     public JsonToken[] TokenTypes { get; set; } 

     public JsonStrictConverter(params JsonToken[] tokenTypes) 
     { 
      TokenTypes = tokenTypes; 
     } 

     public override bool CanConvert(Type objectType) 
     { 
      return objectType == typeof(T); 
     } 
     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      if (reader.TokenType == JsonToken.Null) 
      { 
       if (objectType.IsValueType) 
       { 
        return Activator.CreateInstance(objectType); 
       } 
       return null; 
      } 

      var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)); 
      return (T)converter.ConvertFromString(reader.Value.ToString()); 
     } 
     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      throw new NotImplementedException("The converter '" + this.GetType().Name + "' is not intended to be used when serializing."); 
     } 
     public override bool CanWrite { get { return false; } } 
    } 

deserializacji:

XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents(); 
bodyReader.ReadStartElement("Binary"); 
byte[] rawBody = bodyReader.ReadContentAsBase64(); 
using (MemoryStream ms = new MemoryStream(rawBody)) 
{ 
    using (StreamReader sr = new StreamReader(ms)) 
    { 
     var serializer = new JsonSerializer(); 
     /* These converter are present to enforce strict data type in the json. */ 
     /* by default, newtonsoft can serialize Numbers as strings, strings as boolean, etc.... */ 
     serializer.Converters.Add(new JsonStrictConverter<string>(JsonToken.String)); 
     serializer.Converters.Add(new JsonStrictConverter<bool>(JsonToken.Boolean)); 
     serializer.Converters.Add(new JsonStrictConverter<short>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<ushort>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<int>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<uint>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<long>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<ulong>(JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<float>(JsonToken.Float, JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<double>(JsonToken.Float, JsonToken.Integer)); 
     serializer.Converters.Add(new JsonStrictConverter<decimal>(JsonToken.Float, JsonToken.Integer)); 

     return serializer.Deserialize(sr, typeof(DTO));      
    } 
} 

Czy istnieje ty pe w tym podejściu?

Czy ktoś ma lepsze rozwiązanie?

Dziękuję.

Powiązane problemy