Quantcast
Channel: ASPNETWebStack Issue Tracker Rss Feed
Viewing all articles
Browse latest Browse all 7215

Commented Issue: Overly aggressive validation for applying [DataMember(IsRequired=true)] to required properties with value types [270]

$
0
0
With the default route and this controller:
using System.ComponentModel.DataAnnotations;
using System.Web.Http;

namespace ActionSelectionTest.Controllers
{
[FromUri]
public class Test
{
[Required]
public int ID { get; set; }
}

public class ValuesController : ApiController
{
public string Get(Test test)
{
return test.ID.ToString();
}
}
}

And a GET request to api/values/1 you get this error:

{"Message":"An error has occurred.","ExceptionMessage":"Property 'ID' on type 'ActionSelectionTest.Controllers.Test' is invalid. Value-typed properties marked as [Required] must also be marked with [DataMember(IsRequired=true)] to be recognized as required. Consider attributing the declaring type with [DataContract] and the property with [DataMember(IsRequired=true)].","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Validation.Validators.ErrorModelValidator.Validate(ModelMetadata metadata, Object container)\r\n at System.Web.Http.Validation.ModelValidationNode.ValidateThis(HttpActionContext actionContext, ModelValidationNode parentNode)\r\n at System.Web.Http.Validation.ModelValidationNode.Validate(HttpActionContext actionContext, ModelValidationNode parentNode)\r\n at System.Web.Http.Validation.ModelValidationNode.ValidateChildren(HttpActionContext actionContext)\r\n at System.Web.Http.Validation.ModelValidationNode.Validate(HttpActionContext actionContext, ModelValidationNode parentNode)\r\n at System.Web.Http.ModelBinding.Binders.CompositeModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n at System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder)\r\n at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()\r\n at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator, CancellationToken cancellationToken)"}

Expected result:

We shouldn’t need to require data contract attributes for FromUri types. We should only require the data contract attributes when our formatters that require them are in use.

Workaround:

Remove the validation logic in your config:

config.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);

Comments: The InvalidModelValidatorProvider is there to prevent marking a value type as [Required] and expecting it to work with all the formatters. All of the formatter do not support the [Required] attribute on value types. The XmlMediaTypeFormatter in particular will not raise a model state error for a missing [Required] member, but it will raise an error for a missing [DataMember(IsRequired=true)] member. [DataMember(IsRequired=true)] should work correctly to raise model state errors both for types in the URI and for types from the body and for reference types as well as value types. You don't need [Required] if you have [DataMember(IsRequired=true)]. If you'd like to remove the validator provider, you can do so pretty easily with the one-liner above: config.Services.RemoveAll( typeof(System.Web.Http.Validation.ModelValidatorProvider), v => v is InvalidModelValidatorProvider); This is a good idea if you've removed the XmlMediaTypeFormatter for example, or if all of your [Required] attributes are on types bound from the URI.

Viewing all articles
Browse latest Browse all 7215

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>