我是 .Net 开发新手,所以我想从 .Net Core 类(class)开始。到目前为止,一切都很好;我正在尝试创建一个需要 JSON 对象中存在特定键的 API。如果至少缺少一个键,我认为它是无效的。
[HttpPost("new")]
public IActionResult CreateGPSPoint([FromBody] ModelExample dataObject)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
}
但是,即使我在发送的 JSON 负载中省略了部分或全部键,IsValid 也会返回 true。经过检查,那些丢失的键在后续模型的属性中被设置为 0;这就是我的模型的样子。
public class ModelExample
{
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public float Height{ get; set; }
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal Width{ get; set; }
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int Depth{ get; set; }
//Populated by the entity later, but feel free to critique nevertheless
public int Id { get; set; }
}
请注意,由于此类问题已在其他地方多次提出,因此我尝试了Required(AllowEmptyStrings = false)和DisplayFormat(ConvertEmptyStringToNull = false)的各种组合 - 我的假设是,当JSON 对象被“转换(?)”为模型;然而,结果始终是一样的。
最初我认为这可能是 Automapper(我正在使用的)的问题,但验证在任何实体/模型映射发生之前就通过了。
我错过的那些特定字段也永远不会为 null,因为没有值会被设置为 0(并且 null 无论如何仍然是一个有效值)。
我的想法是将数据解释为 JSON 对象(而不是 ModelExample),并检查这些键是否存在于我的 Controller 逻辑中(类似于 Rails 的“dataObject&.dig[:key]”) - 但是我不知道这是否可能或合适,或者是否有我错过的 .Net 策略。
我的问题确实是;是否有什么地方做得不正确,或者上面遗漏了什么?
如果有人能够提供有关上述工作原理的启发,非常感谢!
最佳答案
当类属性初始化时,它们会得到 default value .
对于引用类型,这是NULL
,对于结构,该值可能会有所不同。
float
、decimal
和 int
都是结构体,并被初始化为相当于 0
的值。
例如public int 深度 { get;放; }
将被初始化为 0
。
您发送一个没有这些属性或未定义这些属性的 JSON 对象,并且它们不会被设置,这意味着始终使用默认值 0
。
0
存在,因此满足“required”的验证。
要解决此问题,请将属性类型设为 nullable .
例如
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public float? Height{ get; set; }
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal? Width{ get; set; }
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int? Depth{ get; set; }
这样,当 JSON 中未定义属性时,它们将获得 NULL
值,并且 NULL
不满足“必需”验证。
例如公共(public)整数?深度{得到;放; }
将被初始化为 NULL
。
另一个选项是使用 BindRequiredAttribute .
Indicates that a property is required for model binding. When applied to a property, the model binding system requires a value for that property. When applied to a type, the model binding system requires values for all properties that type defines.
例如
[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public float Height{ get; set; }
[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal Width{ get; set; }
[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int Depth{ get; set; }
The BindRequired attribute [...] is useful to ensure form data is complete. When applied to a property, the model binding system requires a value for that property.
关于c# - 当省略 "required"JSON 键时,.Net Core 2.1 MVC 中的验证不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52717958/