Jea*_*ois 8 .net wcf serialization json.net deserialization
在我正在开发的项目中,我们开始使用Json.Net库.
但是,我发现json.net在字符串类型上是"松散的".
这是一个例子:
DTO课程
[JsonObject]
public class DTO
{
[JsonProperty]
public string type;
}
Run Code Online (Sandbox Code Playgroud)
反序列化
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));
}
}
Run Code Online (Sandbox Code Playgroud)
这会将'type'属性反序列化为"True".但是,我希望它失败并抛出异常,因为类型不匹配.如果我在json中将true替换为1,它也会这样做.属性'type'值为"1".
问题:
有没有办法强制执行严格的序列化?
是否有其他类型的字符串具有隐式转换,就像我们在这里看到的那样?
谢谢.
JF
我想出了一个解决方法。
虽然它有效,但我不知道这是否是解决我的“问题”的好方法。
我使用转换器来转换
这就是我所做的:
[JsonObject]
public class DTO
{
[JsonProperty]
public string type;
}
Run Code Online (Sandbox Code Playgroud)
自定义转换器:
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; } }
}
Run Code Online (Sandbox Code Playgroud)
反序列化:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法是否缺少任何类型?
周围有人有更好的解决方案吗?
谢谢。