What is up with the ModelState key naming?

Topics: ASP.NET Web API
Aug 13, 2015 at 9:57 PM
I have the following models, decorated with some annotations:
public class Position
    [Range(-90, 90)]
    public double Lat { get; set; }

    [Range(-180, 180)]
    public double Lon { get; set; }

public class Vehicle
    [Required, StringLength(100)]
    public string Name { get; set; }

    public Position StartPosition { get; set; }

    public Position EndPosition { get; set; }

    public LocalTime StartTime { get; set; }
LocalTime here is from the NodaTime library, configured to work with WebAPI. Only here for example purposes.

In the case of validation errors, I want to use Web API's model state object to detect what's wrong. However, it seems to be inconsistent in how it names the properties. For example, if I submit the following very incorrect object:
   name: null,
   startPosition: "middle of nowhere",
   endPosition: { lat: 5000, lon: 0 },
   localTime: 'abc'
Then I'll get back the following keys in my modelState (errors not included):
As you can see, there is a mix of Pascal- and camel- casing! I can't figure out why this is. As you can see, if a Position-typed property is invalid, it gets camel-based, but if it's one of the properties within in, then it's pascal-cased (as is the property on which validation failed).

Is there a reason this happens? It makes detection of the errors a bit inconsistent. I know I could do case-insensitive searches, but I'm curious as to why it's happening.
Aug 14, 2015 at 12:06 AM
The issue here is that the ModelState entries are coming from two different places. Errors encountered while parsing the JSON (i.e. in the JsonMediaTypeFormatter) are added using the names Json.NET provides -- in this case with lowercase initial letters. Validation errors (for missing and out-of-range values) are added using property names.

IIRC it's possible to configure Json.NET to map names differently when reporting errors but I'm not sure of the details.
Aug 14, 2015 at 10:11 AM
Thanks. That makes sense.