Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
436 views
in Technique[技术] by (71.8m points)

c# - Use different name for serializing and deserializing with Json.Net

I am receiving JSON data from a web API that looks like this:

[
  {
    "id": 1
    "error_message": "An error has occurred!"
  }
]

I deserialize this data to objects of the following type:

public class ErrorDetails
{
    public int Id { get; set; }

    [JsonProperty("error_message")]
    public string ErrorMessage { get; set; }
}

Later in my application I would like to serialize the ErrorDetails object again to JSON but using the property name ErrorMessage instead of error_message. So the result would look like this:

[
  {
    "Id": 1
    "ErrorMessage": "An error has occurred!"
  }
]

Is there an easy way I can accomplish this with Json.Net? Perhaps using a custom resolver and some attributes like:

public class ErrorDetails
{
    public int Id { get; set; }

    [SerializeAs("ErrorMessage")]
    [DeserializeAs("error_message")]
    public string ErrorMessage { get; set; }
}

But the resolver doesn't tell me when I'm serializing or deserializing.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!'}"


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...