I have a .net core 3.0 preview 6 MVC application and API. In the API, I am using a third party class library (that I can't change) which defines the class properties as Pascal cased with the JsonProperty, PropertyName snaked cased eg...
public class Company
{
[JsonProperty(PropertyName = "company_name")]
public string CompanyName { get; set; }
more properties ….
}
The problem is that when I supply these via the api they reach the MVC app as Camel case (the default for .net core 3)... and then can't be Deserialized back the to the class model.
Not matter what I try, the API always produces camel cased JSon, eg. the property above will be called companyName.
I tried,
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver { NamingStrategy = new CamelCaseNamingStrategy { OverrideSpecifiedNames = true } };
options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new DefaultNamingStrategy { OverrideSpecifiedNames = true } };
I've tried NamingStrategy = null on both camel and default ContractResolver. Also tried setting the NamingStrategy to Snake
But nothing changes the outputted Json, it's always camelcased.
I can see the resulting string is camel cased by using ReadAsStringAsync in the MVC app... I when I use JsonConvert.DeserializeObject, the properties are always null, because neither the name or Json PropertyName match the names in the resulting string.
Is this a bug in .net core previews or am missing something else?
Thanks Mustafa, your suggested duplicate is kinda the same issue with kinda the same solutions that I've already tried i.e. changing the setting of the ContractResolver / NamingStrategy to different values.... however, My issue is that none of the suggested solutions appear to have any effect on the API response it always comes back as camelCased.
Interestingly, when I change the NamingStrategy to say Snake, Swagger shows the schema as set (i.e. snake) but the actual output is still camelCased!!!
Also, I have no control over the base classes so I can't change the names / json properties of the classes I'm attempting to transmit.
Not really sure where the issue was but had a feeling it was something to do with the mix of Newtonsoft.Json, Json.Net, Swagger and the fact that I was using the Microsoft.AspNet.WebApi.Client to get the HttpContent.ReadAsAsync….all having different Json's
So, I decided to start again with a real simple app and api using the new System.Text.Json included in .Net Core preview (and none of the other libraries). Also not using the HttpContent.ReadAsAsync but instead reading the response as a string and then deserializing with the new library (System.Text.Json)
Doing this I had exactly the same issue …. neither the property name or Json PropertyName match the names in the api returned string i.e class property name = "CompanyName" and Json PropertyName = "company_name" and the api supplied json name = "companyName". So the value isn't set when Deserializing.
However, in the new System.Text.Json options I'm able to specify PropertyNameCaseInsensitive = true, which fixes my problem, now companyName does equal CompanyName and the class model values are set correctly when Deserializing.
So my api call methods end up looking like this...
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("Companies?aCompanyName={0}", aCompanyName));
using HttpResponseMessage response = await Client.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode == false)
{
throw new ApiException
{
StatusCode = (int)response.StatusCode,
Content = content
};
}
_JsonOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
return JsonSerializer.Deserialize<IEnumerable<Company>> (content, _JsonOptions);
I did attempt to set the JsonSerializerOptions globally in the startup class but this didn't work.
I've transferred this approach to all my http calls in my app, removed all references to Newtonsoft and it all works.