First it works, but today it failed!
This is how I define the date property:
[Display(Name = "Date")] [Required(ErrorMessage = "Date of Submission is required.")] [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] [DataType(DataType.Date)] public DateTime TripDate { get; set; }
It has been working in the past. But today, when I call the same ApiController action:
[HttpPost] public HttpResponseMessage SaveNewReport(TripLeaderReportInputModel model)
The Firebug reports:
ExceptionMessage: "Property 'TripDate' on type 'Whitewater.ViewModels.Report.TripLeaderReportInputModel' 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"
What happened? Isn't those [DataContract]
for WCF
? I am using the REST WebAPI
in MVC4
!
Can anyone help? please?
---update---
There are some similar links I have found.
MvC 4.0 RTM broke us and we don't know how to fix it RSS
--- update again ---
Here is the HTTP Response Header:
Cache-Control no-cache Connection Close Content-Length 1846 Content-Type application/json; charset=utf-8 Date Thu, 06 Sep 2012 17:48:15 GMT Expires -1 Pragma no-cache Server ASP.NET Development Server/10.0.0.0 X-AspNet-Version 4.0.30319
Request Header:
Accept */* Accept-Encoding gzip, deflate Accept-Language en-us,en;q=0.5 Cache-Control no-cache Connection keep-alive Content-Length 380 Content-Type application/x-www-form-urlencoded; charset=UTF-8 Cookie .ASPXAUTH=1FF35BD017B199BE629A2408B2A3DFCD4625F9E75D0C58BBD0D128D18FFDB8DA3CDCB484C80176A74C79BB001A20201C6FB9B566FEE09B1CF1D8EA128A67FCA6ABCE53BB7D80B634A407F9CE2BE436BDE3DCDC2C3E33AAA2B4670A0F04DAD13A57A7ABF600FA80C417B67C53BE3F4D0EACE5EB125BD832037E392D4ED4242CF6 DNT 1 Host localhost:39019 Pragma no-cache Referer http://localhost:39019/Report/TripLeader User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0 X-Requested-With XMLHttpRequest
--- update ---
I have found out a makeshift solution. See answer below. If anyone understand why it works or has better solutions, please post your answers. Thank you.
ValidationAttribute, has an important property, ErrorMessage. This property get or set the custom validation message in case of error.
Data annotations (available as part of the System. ComponentModel. DataAnnotations namespace) are attributes that can be applied to classes or class members to specify the relationship between classes, describe how the data is to be displayed in the UI, and specify validation rules.
DataAnnotations namespace includes the following validator attributes: Range – Enables you to validate whether the value of a property falls between a specified range of values. RegularExpression – Enables you to validate whether the value of a property matches a specified regular expression pattern.
DataAnnotations is used to configure your model classes, which will highlight the most commonly needed configurations. DataAnnotations are also understood by a number of . NET applications, such as ASP.NET MVC, which allows these applications to leverage the same annotations for client-side validations.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With