使用不同的名称使用 Json.Net 进行序列化和反序列化 [英] Use different name for serializing and deserializing with Json.Net

查看:18
本文介绍了使用不同的名称使用 Json.Net 进行序列化和反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从如下所示的 Web API 接收 JSON 数据:

<预><代码>[{身份证":1"error_message": "发生错误!"}]

我将此数据反序列化为以下类型的对象:

公共类ErrorDetails{公共 int Id { 获取;放;}[JsonProperty("error_message")]公共字符串 ErrorMessage { 获取;放;}}

稍后在我的应用程序中,我想再次将 ErrorDetails 对象序列化为 JSON,但使用属性名称 ErrorMessage 而不是 error_message.所以结果应该是这样的:

<预><代码>[{身份证":1"ErrorMessage": "发生错误!"}]

有没有一种简单的方法可以使用 Json.Net 完成此任务?也许使用自定义解析器和一些属性,如:

公共类ErrorDetails{公共 int Id { 获取;放;}[SerializeAs("ErrorMessage")][DeserializeAs("error_message")]公共字符串 ErrorMessage { 获取;放;}}

但是解析器不会告诉我何时序列化或反序列化.

解决方案

您可以使用 JsonSerializerSettings、ContractResolver 和 NamingStrategy.

公共类ErrorDetails{公共 int Id { 获取;放;}公共字符串 ErrorMessage { 获取;放;}}var json = "{'Id': 1,'error_message': '发生错误!'}";

对于去序列化,您可以使用 SnakeCaseNamingStrategy.

var dezerializerSettings = new JsonSerializerSettings{ContractResolver = 新的 DefaultContractResolver{NamingStrategy = new SnakeCaseNamingStrategy()}};var obj = JsonConvert.DeserializeObject(json, dezerializerSettings);

要再次序列化对象,您不必更改 JsonSerializerSettings,因为默认情况下将使用属性名称.

var jsonNew = JsonConvert.SerializeObject(obj);

<块引用>

jsonNew = "{'Id': 1,'ErrorMessage': '发生错误!'}"

<小时>

或者您可以创建一个可以决定使用哪个名称的合同解析器.然后你可以决定何时去序列化和序列化是使用 pascal 大小写名称格式还是带下划线的格式.

公共类 CustomContractResolver : DefaultContractResolver{public bool UseJsonPropertyName { get;}公共 CustomContractResolver(bool useJsonPropertyName){UseJsonPropertyName = useJsonPropertyName;}受保护的覆盖 JsonProperty CreateProperty(MemberInfo 成员,MemberSerialization memberSerialization){var property = base.CreateProperty(member, memberSerialization);if (!UseJsonPropertyName)property.PropertyName = property.UnderlyingName;归还财产;}}公共类错误详细信息{公共 int Id { 获取;放;}[JsonProperty("error_message")]公共字符串 ErrorMessage { 获取;放;}}var json = "{'Id': 1,'error_message': '发生错误!'}";var serializerSettings = new JsonSerializerSettings(){ContractResolver = new CustomContractResolver(false)};var dezerializerSettings = 新的 JsonSerializerSettings{ContractResolver = new CustomContractResolver(true)};var obj = JsonConvert.DeserializeObject(json, dezerializerSettings);var jsonNew = JsonConvert.SerializeObject(obj, serializerSettings);

<块引用>

jsonNew = "{'Id': 1,'ErrorMessage': '发生错误!'}"

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.

解决方案

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

这篇关于使用不同的名称使用 Json.Net 进行序列化和反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆