【问题标题】:Change json property name in output using Json.Net [duplicate]使用 Json.Net 在输出中更改 json 属性名称 [重复]
【发布时间】:2018-01-19 19:45:39
【问题描述】:

我正在尝试读取 JSON 文件,重命名属性名称,并使用新名称导出新的 JSON。如本例中所述,https://www.newtonsoft.com/json/help/html/JsonPropertyName.htm,我们可以使用 JsonProperty 在代码内部指定不同的名称。但是,当您导出 json 时,它会返回原始名称。因此,在示例中,当它登录控制台时,它仍然返回“release_date”而不是“ReleaseDate”。有没有办法在不创建全新对象的情况下做到这一点?

为了澄清问题,这是我正在尝试做的示例:

JSON 输入:

{ "name": "Starcraft", "release_date": "1998-01-01T00:00:00" }

Object 用于反序列化数据:

public class Videogame
{
    public string name{ get; set; }

    [JsonProperty("release_date")]
    public DateTime releaseDate { get; set; }
}

被调用的代码:

var json = JsonConvert.DeserializeObject<Videogame>(File.ReadAllText(path))
Console.WriteLine(JsonConvert.SerializeObject(json));

结果输出:

{ "name": "Starcraft", "release_date": "1998-01-01T00:00:00" }

期望的输出:

{ "name": "Starcraft", "releaseDate": "1998-01-01T00:00:00" }

我目前知道如何解决它的唯一方法是创建一个新对象并使用它来序列化我的输出。不确定是否有更简单的方法来做到这一点。

【问题讨论】:

标签: c# serialization json.net


【解决方案1】:

您可以使用自定义解析来创建所需的行为:

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);

NtFreX his answer 致敬。我提供我的,以便您表明您的问题已解决。

【讨论】:

  • @dbc 实际上,我认为最好留下重复的徽章并删除我的答案,因为它非常相似。几分钟后就能搞定。
  • 哦,其实我做不到。届时将包括原作者。
【解决方案2】:

以下将起作用:

public class Videogame
{
    public string name{ get; set; }

    [JsonProperty("release_date")]
    public DateTime old 
    { 
          set { ReleaseDate = value; }
    }

    [JsonProperty("releaseDate")]
    public DateTime ReleaseDate { get; set; }
}

反序列化时,旧属性会将其值重定向到新属性。

由于旧的属性只是一个setter,它不会被序列化回来。

我不会考虑将这种方法用于大量重命名。那么最好遵循 cmets 中给出的建议。

【讨论】:

  • 不错的解决方案,易于实施
猜你喜欢
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多