You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.
"Required" non-nullable properties will never raise a corresponding model validation error if the property is entirely omitted from the request body. Given the following request body sent to the Post action:
[BindRequired]: This attribute adds a model state error if binding cannot occur.
[Required]: Makes a property required.
It also appears to be difficult to replace the built-in convention and achieve the desired behavior (which is a validation error if a required or binding required property is omitted).
One of the top search results for this issue is this blog post where the author explains a workaround which no longer works:
Similarly, it seems none of the usual hooks for custom validation can tell if the value was bound to a value in the request or if it just assumed the default value for the non-nullable type. I've explored:
Using IModelValidatorProvider / IModelValidator to check the ModelValidationContext (the context has a Model value of the assumed default 0).
Using IBindingMetadataProvider to make sure IsBindingRequired is true (as per the above example).
Using IValidationMetadataProvider to make sure IsRequired is true (no effect).
The only work-around I've found is to change the property to a nullable type (int?). This seems like a poor solution since:
Usage of the model property is more verbose: Value.Value.
Static analysis tools will identify this usage as a possible NRE.
This has also been discussed in issues #6825, #5391, and #3971, but none provide a resolution.
Is there any way to achieve this desired behavior by convention, and should this not be the default behavior?
Version of Microsoft.AspNetCore.Mvc or Microsoft.AspNetCore.App or Microsoft.AspNetCore.All:
I've tried this on both:
2.1.0-rc1-final
2.0.5
The text was updated successfully, but these errors were encountered:
[BindRequired] is a feature inextricably tied to the MVC model binding system and none of the supported input formatters supports it. But for JSON.NET, use [JsonProperty(Required = true)] instead.
[Required] is a .NET attribute with very specific, documented semantics:
A validation exception is raised if the property is null, contains an empty string (""), or contains only white-space characters.
I've spent the better part of the day running through most of @mpetito steps above (while introducing [ApiController]). I think if anything, the documentation for BindRequiredAttribute should be updated to call out the limitations and workaround @dougbu mentioned. The distinction between model binding and input formatters is far from obvious until you start to really dig into this.
IMHO, the TestRequest model above really should fail validation when MVC handles posted JSON of {}.
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Is this a Bug or Feature request?:
Bug as it seems to contradict official documentation and is surprising behavior.
Steps to reproduce (preferrably a link to a GitHub repo with a repro project):
Create a new project
dotnet new webapi
and modify a controller as follows:Description of the problem:
"Required" non-nullable properties will never raise a corresponding model validation error if the property is entirely omitted from the request body. Given the following request body sent to the Post action:
The controller responds with:
Per the docs for binding and similarly the docs for validation it is unexpected that a missing property in the json passes validation.
It also appears to be difficult to replace the built-in convention and achieve the desired behavior (which is a validation error if a required or binding required property is omitted).
One of the top search results for this issue is this blog post where the author explains a workaround which no longer works:
Code within the default model binders declare that binding is successful if the property is non-nullable and the bound value is null:
Mvc/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/SimpleTypeModelBinder.cs
Lines 141 to 151 in c922b0b
Similarly, it seems none of the usual hooks for custom validation can tell if the value was bound to a value in the request or if it just assumed the default value for the non-nullable type. I've explored:
IModelValidatorProvider
/IModelValidator
to check theModelValidationContext
(the context has aModel
value of the assumed default0
).IBindingMetadataProvider
to make sureIsBindingRequired
is true (as per the above example).IValidationMetadataProvider
to make sureIsRequired
is true (no effect).The only work-around I've found is to change the property to a nullable type (
int?
). This seems like a poor solution since:Value.Value
.This has also been discussed in issues #6825, #5391, and #3971, but none provide a resolution.
Is there any way to achieve this desired behavior by convention, and should this not be the default behavior?
Version of
Microsoft.AspNetCore.Mvc
orMicrosoft.AspNetCore.App
orMicrosoft.AspNetCore.All
:I've tried this on both:
The text was updated successfully, but these errors were encountered: