Dot-Net
Json.net 鬆散與嚴格類型反序列化
在我正在進行的項目中,我們開始使用 Json.Net 庫。
但是,我剛剛發現 json.net 在字元串類型上是“鬆散的”。
這是一個例子:
DTO 類
[JsonObject] public class DTO { [JsonProperty] public string type; }反序列化
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)); } }這會將“type”屬性反序列化為“True”。但是,我希望它會失敗並拋出異常,因為存在類型不匹配。如果我在 json 中將 true 替換為 1,它的作用相同。屬性“類型”的值為“1”。
問題:
- 有沒有辦法強制執行嚴格的序列化?
- 除了字元串之外,還有其他類型像我們在這裡看到的那樣具有隱式轉換嗎?
謝謝你。
傑夫
我想出了一個解決方法。
雖然它有效,但我不知道這是否是解決我的“問題”的好方法。
我使用轉換器從
這是我所做的:
[JsonObject] public class DTO { [JsonProperty] public string type; }自定義轉換器:
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; } } }反序列化:
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)); } }這種方法中是否缺少任何類型?
周圍有沒有更好的解決方案?
謝謝你。