第三方 JSON API 中的两个不同值,使 Newtonsoft 中断
two different values in third party JSON API, making Newtonsoft break
嗨,我希望你能帮上忙。
我正在将来自第三方 API 的 Stocks 数据转换为 c# 数据类型,但问题是,JSON 对象有多个值。
例如:
"sharesShortPriorMonth":{"raw":4680878,"fmt":"4.68M","longFmt":"4,680,878"}
我想要的是 fmt 值 (4.68M)
,我正在尝试将其放入 C# 字段 public string sharesShortPriorMonth { get; set; }
我的问题是,当我从 JSON 字符串反序列化时,它期待更像 "sharesShortPriorMonth": "4.68M"
的东西
如何告诉 Json.NET 取那个值?
我已经检查了文档,JSON属性 属性不是我想要的,因为它映射了不同的名称。不是子值。
提前致谢。
您需要将 sharesShortPriorMonth
更改为代表现有 json 结构的类型(您可以只包含需要的属性):
public SharesShortPriorMonth sharesShortPriorMonth { get; set; }
public class SharesShortPriorMonth
{
public string fmt { get; set; }
}
或创建custom converter and mark field with corresponding attribute.
我会用这样的东西
public class Stocks
{
... another properties
[JsonProperty("sharesShortPriorMonth")]
public JObject sharesShortPriorMonthJo { set { sharesShortPriorMonth = (string) value["fmt"]; }}
[JsonIgnore]
public string sharesShortPriorMonth { get; private set;}
}
就我个人而言,我会选择@Serge 的解决方案(但我认为 sharesShortPriorMonthJo
属性 应该是 private
因为从外面看没有必要,但对于客户)。如果你想让你的 class 尽可能干净,那么你可以使用自定义的 JsonConverter
,正如 @GuruStron 所指出的。但是,复杂度刚好移到另一个class,正好是JsonConverter
。
您可以使用的最简单的 (?) JsonConverter
是:
public class CustomConverter : JsonConverter<string>
{
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var tokens = new Dictionary<string, object>();
serializer.Populate(reader, tokens);
return (string) tokens["fmt"] ?? throw new JsonReaderException(@"""fmt"" not found in sharesShortPriorMonth");
}
}
Populate
方法在这种情况下非常方便,因为我们可以填写一个包含所有 json 属性的字典,最终我们只需要检索 fmt
属性.
Stocks
class变为:
public class Stocks
{
[JsonConverter(typeof(CustomConverter))]
public string sharesShortPriorMonth { get; set; }
}
嗨,我希望你能帮上忙。
我正在将来自第三方 API 的 Stocks 数据转换为 c# 数据类型,但问题是,JSON 对象有多个值。
例如:
"sharesShortPriorMonth":{"raw":4680878,"fmt":"4.68M","longFmt":"4,680,878"}
我想要的是 fmt 值 (4.68M)
,我正在尝试将其放入 C# 字段 public string sharesShortPriorMonth { get; set; }
我的问题是,当我从 JSON 字符串反序列化时,它期待更像 "sharesShortPriorMonth": "4.68M"
如何告诉 Json.NET 取那个值?
我已经检查了文档,JSON属性 属性不是我想要的,因为它映射了不同的名称。不是子值。
提前致谢。
您需要将 sharesShortPriorMonth
更改为代表现有 json 结构的类型(您可以只包含需要的属性):
public SharesShortPriorMonth sharesShortPriorMonth { get; set; }
public class SharesShortPriorMonth
{
public string fmt { get; set; }
}
或创建custom converter and mark field with corresponding attribute.
我会用这样的东西
public class Stocks
{
... another properties
[JsonProperty("sharesShortPriorMonth")]
public JObject sharesShortPriorMonthJo { set { sharesShortPriorMonth = (string) value["fmt"]; }}
[JsonIgnore]
public string sharesShortPriorMonth { get; private set;}
}
就我个人而言,我会选择@Serge 的解决方案(但我认为 sharesShortPriorMonthJo
属性 应该是 private
因为从外面看没有必要,但对于客户)。如果你想让你的 class 尽可能干净,那么你可以使用自定义的 JsonConverter
,正如 @GuruStron 所指出的。但是,复杂度刚好移到另一个class,正好是JsonConverter
。
您可以使用的最简单的 (?) JsonConverter
是:
public class CustomConverter : JsonConverter<string>
{
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var tokens = new Dictionary<string, object>();
serializer.Populate(reader, tokens);
return (string) tokens["fmt"] ?? throw new JsonReaderException(@"""fmt"" not found in sharesShortPriorMonth");
}
}
Populate
方法在这种情况下非常方便,因为我们可以填写一个包含所有 json 属性的字典,最终我们只需要检索 fmt
属性.
Stocks
class变为:
public class Stocks
{
[JsonConverter(typeof(CustomConverter))]
public string sharesShortPriorMonth { get; set; }
}