Why are ApiController and Controller's ModelState are so different?
Recently I use ASP.net Web API to build a small project. I met some problems in returning server side model validation messages. Then I built a small test project and created a model like that:
public class Contact : IValidatableObject { [Required] public string FullName { get; set; } [RegularExpression(@"^\d[-,\d]*\d$", ErrorMessage = "Phone number is incorrect.")] public string PhoneNumber { get; set; } [RegularExpression(@"^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$", ErrorMessage = "Email format is incorrect.")] public string Email { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (this.Email == null && this.PhoneNumber == null) yield return new ValidationResult("Email and phone number can not both be empty.", new string[] { "PhoneNumber", "Email" }); } }
I also created two controllers to test it. The Web API controller:
public class ContactController : ApiController { public HttpResponseMessage Post([FromBody]Contact ct) { HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK); msg.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(ModelState)); return msg; } }
The MVC controller:
public class ContactMvcController : Controller { [HttpPost] public ActionResult Contact(Contact ct) { return Content(Newtonsoft.Json.JsonConvert.SerializeObject(ModelState)); } }
After that, I use fiddler to post a request to test it:
Http headers ----
content-type: application/json
Content-Length: 28
Http content ----
{"FullName":"Jiang Guogang"}
Then I got very different result. The MVC controller:
Noticing that all properties are contained in result whatever it has error or not. And look at the Web API controller:
That's strange. I want to know the reason why they are so different.
Personally, I think the MVC controller does better.
I also compared the prototype of the two ModelStates. They are little difference althought they are in different namespaces and libraries.
MvcController's ModelState | namespace System.Web.Mvc | System.Web.Mvc.dll |
Web API Controller's ModelState | namespace System.Web.Http.ModelBinding | System.Web.Http.dll |
Does that make sense?