Ste*_*ath 5 c# string json json.net deserialization
JSON看起来像这样:
{
"x": "50"
}
Run Code Online (Sandbox Code Playgroud)
这堂课看起来像这样:
public class Test
{
public float? x { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并在使用时
var test = JsonConvert.DeserializeObject<Test>(json);
Run Code Online (Sandbox Code Playgroud)
抛出没有异常,JSON.NET只是将字符串值"50"转换为浮点值50.0.
这个问题是在输入验证的背景下提出的.我想获得一个异常,因为JSON字符串不符合合同(该x字段应该是一个真正的浮点数).
我不想在'Test'类中使用属性注释.
是否有可以用来避免这种情况的JsonSerializerSettings?
JSON.NET自由地将数字字符串("50")解析为数字.据我所知,没有琐碎的方法可以解决这个问题.
您可以创建一个不允许这样的自定义转换器:
public class NumberConverter : JsonConverter
{
private readonly Type[] _typesNotToReadAsString = { typeof(float), typeof(float?) };
public override bool CanConvert(Type objectType)
{
return _typesNotToReadAsString.Any(t => t.IsAssignableFrom(objectType));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (_typesNotToReadAsString.Contains(objectType) && token.Type == JTokenType.String)
{
string exceptionString = string.Format("Won't convert string to type {0}", objectType.FullName);
throw new JsonSerializationException(exceptionString);
}
return token.ToObject(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanWrite
{
get { return false; }
}
}
Run Code Online (Sandbox Code Playgroud)
该转换器报告能够反序列化为指定类型,在这种情况下float和float?,但配置.
反序列化后,它会检查令牌类型.给定JSON输入的一些令牌类型:
"50": JTokenType.String50: JTokenType.Integer 42.1415: JTokenType.Float这样,转换器可以确定当前令牌是否按需要格式化.当令牌类型是一个字符串时,上面的转换器将抛出一个异常,表明它不会将字符串转换为所需的类型.
当令牌类型为其他任何内容时,转换器会将令牌转换为适当的数字类型token.ToObject(objectType).该方法还将通过抛出相应的异常来处理非数字输入,例如"无法将数组转换为单个"..
给出一个类Foo:
public class Foo
{
public float Bar { get; set; }
public string Baz { get; set; }
public float? Qux { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用上面的转换器反序列化JSON字符串,这将工作:
var jsonString = "{ \"Bar\" : 50, \"Baz\" : \"zaB\", \"Qux\" : 42.1415 }";
var foo = JsonConvert.DeserializeObject<Foo>(jsonString, new NumberConverter());
Run Code Online (Sandbox Code Playgroud)
虽然这将抛出:
var jsonString = "{ \"Bar\" : 50, \"Baz\" : \"zaB\", \"Qux\" : \"42.1415\" }";
var foo2 = JsonConvert.DeserializeObject<Foo>(jsonString, new NumberConverter());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
640 次 |
| 最近记录: |