First it works, but today it failed!
This is how I define the date property:
[Display(Name = \"Date\")]
[Required(ErrorMessage = \"Date of Submissio
Okay. Though I have not complete understood this thing. A workaround is found.
In Global.asax
:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
I found it in the Issue Tracker in aspnetwebstack. Here is the link to the page:
Overly aggressive validation for applying [DataMember(IsRequired=true)] to required properties with value types
If anyone can tell us why it is like this, please post your insight as answers. Thank you.
I have added a ModelValidationFilterAttribute
and made it work:
public class ModelValidationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
// Return the validation errors in the response body.
var errors = new Dictionary<string, IEnumerable<string>>();
//string key;
foreach (KeyValuePair<string, ModelState> keyValue in actionContext.ModelState)
{
//key = keyValue.Key.Substring(keyValue.Key.IndexOf('.') + 1);
errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage);
}
//var errors = actionContext.ModelState
// .Where(e => e.Value.Errors.Count > 0)
// .Select(e => new Error
// {
// Name = e.Key,
// Message = e.Value.Errors.First().ErrorMessage
// }).ToArray();
actionContext.Response =
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
}
}
}
You can either add [ModelValidation]
filter on the actions. Or add it into Global.asax.cs
:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
In this way, I continue to use the original data annotation.
Reference
UPDATE 24-5-2013: The InvalidModelValidatorProvider
responsible for this error message has been removed from the ASP.NET technology stack. This validator proofed to cause more confusion than it was meant to solve. For more information, see the following link: http://aspnetwebstack.codeplex.com/workitem/270
When you decorate your class with [DataContract]
attribute, you need to explicitly decorate the members you would want to serialize with the [DataMember]
attribute.
The issue is that DataContractSerializer
does not support the [Required]
attribute. For reference types, we're able to check that the value is not null after deserialization. But for value types, there is no way for us to enforce the [Required]
semantics for DataContractSerializer
without [DataMember(IsRequired=true)]
.
So you could end up marking an DateTime
as [Required]
and expect a model validation error if the DateTime
isn't sent, but you'd just get a DateTime.MinValue
value and no validation error instead.
If you are attempting to return the output of your action as XML, then you will need to use DataContracts as they are required by the default serializer. I am guessing that you had previously been requesting the output of your action as Json, the Json serializer does not require data contracts. Can you post a fiddle of your request?