DataAnnotation for Required property

淺唱寂寞╮ 提交于 2019-11-27 18:44:41
Blaise

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?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!