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: Verified.
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: Verified.