C# Json.Net Convention That Follows Ruby Property Naming Conventions

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



Leave a reply



Submit