避免将任何数字绑定到布尔属性
Posted
技术标签:
【中文标题】避免将任何数字绑定到布尔属性【英文标题】:Avoid bind any number to bool property 【发布时间】:2020-04-15 15:30:26 【问题描述】:我有简单的带有模型的 ASP.NET Core WebApi
public class Model
public bool? Value get; set;
和端点
[HttpPost]
public async Task<IActionResult> Create([FromBody] Model model)
当我使用正文发出 POST 请求时
"Value" : 7676
或
"Value" : 2955454545645645645645645645654534534540
然后model.Value == true
如何避免这种情况?在这种情况下我需要一些错误,因为7676
不是布尔值。
我找到了this question 和this,但解决方案不适合我,因为我在不同的项目中有很多模型(因此,很难将 JsonConverter 属性从答案添加到所有属性)
另外,我正在寻找任何描述这种行为的文档。
【问题讨论】:
编写自定义模型绑定器并使用它 当您尝试发布无效的 Json 属性值时,您应该会收到类似“无法将 JSON 值转换为 System.Nullable`1[System.Boolean]。路径:$.Value”的错误。您使用的是哪个版本的 asp.net core? @vendettamit 是的,我也这么认为,但行为就像我描述的那样。 ASP.NET Core 2.2 @Milney 你能帮忙定制模型活页夹吗?我有很多模型,我可以为所有模型中的布尔属性创建活页夹吗?我试过这个docs.microsoft.com/en-us/aspnet/core/mvc/advanced/…,但总是得到ValueProviderResult.None
创建一个从JsonConverter
派生的自定义MyBookConverter
,然后注册services.AddMvc().AddJsonOptions(options => options.SerializerSettings.Converters.Add(new MyBoolConverter()););
【参考方案1】:
您可以通过创建自定义 JsonConverter 来实现。可以找到相同的文档here
这种行为的原因与 JSON.NET 或 System.Text.JSON
反序列化类型的方式有关。由于123可以转换为boolean
true,所以反序列化成功。它根据整数值认为它是真还是假,直到您显式定义如下的 JsonConverter 来检查正在读取的令牌实际上是布尔值。
如果您不使用 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;
或在 Startup 中全局注册
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.Converters.Add(new OnlyBoolean()););
【讨论】:
@Chebur 我已经编辑它以接受“true”“false”1 和 0 作为有效输入。这能回答你的问题吗? 很好的答案。你知道这是否有一个等效的 asp.net 框架吗?以上是关于避免将任何数字绑定到布尔属性的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS:如何在为缺少的属性提供默认值时避免非分配错误?