I'm trying to implement JSON camel casing in my .Net API project. In my start up class I add the following lines:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
As I understand it this is what is required to implement camel casing on all routes. However when I add the following this fails to work, the responses come back as Pascal Case:
RouteTable.Routes.MapHttpRoute(
"DefaultApi",
"{controller}/{id}",
new {id = RouteParameter.Optional}
);
When I remove the above MapHttpRoute line and use Route attributes in the controllers instead camel casing works fine.
Has anyone any idea as to what is happening here?
Before we answer, you should understand first that the camel case API response overriding will NOT affect the Model Validation (we will solve this problem at the end of answer).
FOR YOUR QUESTION:
You have to use the same HttpConfiguration variable so try to use this instead
// config is an HttpConfiguration object
config.Routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
FOR THE MODEL VALIDATION:
You have to create a base controller that all your other controllers should inherit from, then override the ModelStateDictionary by creating a new method that you have to use instead (ModelState is a read-only property) as below (1):
public class BaseApiController : ApiController
{
public ModelStateDictionary ModelStateAsCamelCase()
{
var newModelStateDictionary = new ModelStateDictionary();
foreach (var element in ModelState)
{
if (!string.IsNullOrWhiteSpace(element.Key))
{
var keys = element.Key.Split('.');
List<string> camelKeys = new List<string>();
foreach (var key in keys)
{
camelKeys.Add(key.First().ToString().ToLowerInvariant() + key.Substring(1));
}
// You can (add a / change this) code if the returned key is not
// composed from the ObjectName.Property, such as when it is
// composed from the property name
var newKey = camelKeys.Aggregate((i, j) => i + "." + j);
newModelStateDictionary.Add(newKey, element.Value);
}
else
newModelStateDictionary.Add(element);
}
return newModelStateDictionary;
}
}
this method will edit the model state dictionary string key to comply the camel convention
now inside your action, you can use this method instead of the default ModelState
......
if (!ModelState.IsValid)
return BadRequest(ModelStateAsCamelCase());
......
1- I have checked many answer related to solve the camelCase problem in modelState even in .net core but non has provided a default config solution. as they mentioned that the modelState will not get affected by the default config used in the first part from my answer
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