我有简单的 ASP.NET Core WebApi 和模型
public class Model
{
public bool? Value {get; set;}
}
和端点
[HttpPost]
public async Task<IActionResult> Create([FromBody] Model model)
当我使用 body 发出 POST 请求时
{
"Value" : 7676
}
或
{
"Value" : 2955454545645645645645645645654534534540
}
然后model.Value == true
如何避免这种情况?在这种情况下我需要一些错误,因为 7676
不是 bool 值。
我找到了 this question 和 this ,但解决方案不适合我,因为我在不同的项目中有很多模型(因此,很难将 JsonConverter 属性从答案添加到所有属性)
此外,我正在寻找描述此行为的任何文档。
最佳答案
您可以通过创建自定义 JsonConverter 来实现它。可以找到相同的文档 here
此行为的原因与 JSON.NET 或 System.Text.JSON 反序列化类型的方式有关。由于123可以转换为boolean
true,所以反序列化成功。它根据整数值认为它是 true 或 false,直到您显式定义一个 JsonConverter(如下所示)来检查正在读取的 token 实际上是 bool 值。
如果您不使用 Newtonsoft。您使用System.Text.Json
您可以关注此页面create a custom JSON converter
public class OnlyBoolean : JsonConverter
{
readonly JsonSerializer defaultSerializer = new JsonSerializer();
public override bool CanConvert(Type objectType)
{
return objectType == typeof(bool);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Boolean:
{
return defaultSerializer.Deserialize(reader, objectType);
}
case JsonToken.String:
{
if (reader.Value?.ToString() == "true" || reader.Value?.ToString() == "false")
return defaultSerializer.Deserialize(reader, objectType);
else
throw new JsonSerializationException(string.Format("Token \"{0}\" of type {1} is not a boolean type", reader.Value, reader.TokenType));
}
case JsonToken.Integer:
{
if (Convert.ToInt32(reader.Value) == 1 || Convert.ToInt32(reader.Value) == 0)
return defaultSerializer.Deserialize(reader, objectType);
else
throw new JsonSerializationException(string.Format("Token \"{0}\" of type {1} is not a boolean type", reader.Value, reader.TokenType));
}
default:
throw new JsonSerializationException(string.Format("Value\"{0}\" of type {1} is not a boolean type", reader.Value, reader.TokenType));
}
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后将模型装饰为:
public class Model
{
[JsonConverter(typeof(OnlyBoolean))]
public bool? Value {get; set;}
}
或者在启动中全局注册
services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.Converters.Add(new OnlyBoolean());});
关于c# - 避免将任何数字绑定(bind)到 bool 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59470631/