C# JSON.NET convention that follows Ruby property naming conventions?
Update - September 2016:
Json.NET 9.0.1 has SnakeCaseNamingStrategy. You can use that to have twitter_screen_name style properties automatically.
Inherit from DefaultContractResolver
and override ResolvePropertyName
to format property names as you'd like.
CamelCasePropertyNamesContractResolver
does a similar global change to property names.
How to ignore underscore when deserializing
Not so much ignore but you can decorate with a property name like so:
public class Result
{
[JsonProperty(PropertyName = "long_name")]
public int LongName { get; set; }
}
Deserialize date in json to DateTime object in c#
Turns out System.Text.Json isn’t the issue here, but more the solution.
I’ve removed the using for Newtonsoft.Json.Converters and replaced it with System.Text.Json. Then used the JsonSerializer to Deserialize.
Also removed the IsoDateTimeConverter code.
This seems to work - https://dotnetfiddle.net/UEE3QD
Use different name for serializing and deserializing with Json.Net
You can make use of the JsonSerializerSettings
, the ContractResolver and the NamingStrategy.
public class ErrorDetails
{
public int Id { get; set; }
public string ErrorMessage { get; set; }
}
var json = "{'Id': 1,'error_message': 'An error has occurred!'}";
For dezerialization you could use the SnakeCaseNamingStrategy
.
var dezerializerSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
};
var obj = JsonConvert.DeserializeObject<ErrorDetails>(json, dezerializerSettings);
To serialize the object again you dont have to change the JsonSerializerSettings
as the default will use the property name.
var jsonNew = JsonConvert.SerializeObject(obj);
jsonNew = "{'Id': 1,'ErrorMessage': 'An error has occurred!'}"
Or you could create a contract resolver which can decide which name to use. Then you can decide when you dezerialize and serialize if you want to use the pascal case name format or the one with the underscore.
public class CustomContractResolver : DefaultContractResolver
{
public bool UseJsonPropertyName { get; }
public CustomContractResolver(bool useJsonPropertyName)
{
UseJsonPropertyName = useJsonPropertyName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (!UseJsonPropertyName)
property.PropertyName = property.UnderlyingName;
return property;
}
}
public class ErrorDetails
{
public int Id { get; set; }
[JsonProperty("error_message")]
public string ErrorMessage { get; set; }
}
var json = "{'Id': 1,'error_message': 'An error has occurred!'}";
var serializerSettings = new JsonSerializerSettings()
{
ContractResolver = new CustomContractResolver(false)
};
var dezerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CustomContractResolver(true)
};
var obj = JsonConvert.DeserializeObject<ErrorDetails>(json, dezerializerSettings);
var jsonNew = JsonConvert.SerializeObject(obj, serializerSettings);
jsonNew = "{'Id': 1,'ErrorMessage': 'An error has occurred!'}"
JsonConvert.DeserializeObjectT(JsonString) returning all PropertiesT as Null
The property names in your JSON do not match the property names in your class (because of the underscores), so you are getting default values. You can fix this by decorating the properties in your class with the JsonProperty
attribute and specifying the property name used in the JSON.
Use this class for deserialization
public class SampleResponse
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}
JSON Naming Convention (snake_case, camelCase or PascalCase)
There is no SINGLE standard, but I have seen 3 styles you mention ("Pascal/Microsoft", "Java" (camelCase
) and "C" (underscores, snake_case
)) -- as well as at least one more, kebab-case
like longer-name
).
It mostly seems to depend on what background developers of the service in question had; those with c/c++ background (or languages that adopt similar naming, which includes many scripting languages, ruby etc) often choose underscore variant; and rest similarly (Java vs .NET). Jackson library that was mentioned, for example, assumes Java bean naming convention (camelCase
)
UPDATE: my definition of "standard" is a SINGLE convention. So while one could claim "yes, there are many standards", to me there are multiple Naming Conventions
, none of which is "The" standard overall. One of them could be considered the standard for specific platform, but given that JSON is used for interoperability between platforms that may or may not make much sense.
How to deserialize JSON (snake_case) to dynamic (PascalCase)?
When you call JsonConvert.DeserializeObject<dynamic>
it acts the same way as JsonConvert.DeserializeObject<JObject>
. JObject
is not a real result of the deserialization, but some intermediate state of your data, It is closer to readers than to objects. E.g. it allows you to deserialize only part of a JSON
So seems like JsonConvert.DeserializeObject<dynamic>
creates not a result object but a reach, functional reader for the JSON data. I suppose, that's why it shows you data as it was without any post processing
I suppose it's better to direct that question to a "Newtonsoft.Json" developers.
.Net Core 3.0.100-preview6 - API Json responses are always camelcase, but my classes are not
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.
Related Topics
Reach Control from Another Page. Asp.Net
Communicate Between Two Windows Forms in C#
How to Add User-Supplied Input to an SQL Statement
Sending Email Through Gmail Smtp Server With C#
How Do Parameterized Queries Help Against SQL Injection
What's the Use/Meaning of the @ Character in Variable Names in C#
There Is Already an Open Datareader Associated With This Command Which Must Be Closed First
Most Efficient Way to Concatenate Strings
How to Handle Both a Single Item and an Array For the Same Property Using Json.Net
Mvvm: Tutorial from Start to Finish
How to Turn a C# Object into a Json String in .Net
Capture Screenshot of Active Window
What Are the Correct Version Numbers For C#