c# - 避免将任何数字绑定(bind)到 bool 属性

标签 c# asp.net-core asp.net-web-api asp.net-core-webapi

我有简单的 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 questionthis ,但解决方案不适合我,因为我在不同的项目中有很多模型(因此,很难将 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/

相关文章:

c# - float 和 double 之间不明确的扩展方法调用

c# - 更改 Action 的线程优先级

c# - 授权策略的依赖注入(inject)

asp.net-core - .NET Core Web API API key 认证 AllowAnonymous

c# - Linq to SQL .Sum() 没有组...进入

c# - 如何产生精确定时的音调和静音?

asp.net-core - ActionResult<bool> 中的隐式转换运算符不起作用

c# - JWT承载 token 授权不起作用ASP Net Core Web API

c# - 使用 ODATA 过滤 x 和 y 之间的日期

asp.net-mvc-3 - 在 MVC3 项目中使用 Apicontroller