c#Newtonsoft-json:如何反序列化json并获取float字段的原始字符串



考虑json字符串:

var json = "{"myfield":5e-0000006}";

我想要反序列化json,并获取字段"myfield";作为原始字符串。示例:

JToken tok = <Deserialize> // how do this??
var val = tok["myfield"].ToString(); // need get "5e-0000006"

我需要获得原始字符串中的精确字符串值(例如"5e-0000006",但它可以是任何有效的浮点字符串)。

有一些信息和灵感,来自:

  • 您不需要编写任何转换器,只需使用以下JRaw类型即可:
  • 文档:此示例将JSON反序列化为对象
static void Main(string[] args)
{
var json = "{"myfield":5e-0000006}";
MyJson j = JsonConvert.DeserializeObject<MyJson>(json);
string mf = j.myfield;
Console.WriteLine(mf);
}
public class MyJson 
{
[JsonProperty("myfield")]
public string myfield { get; set; }
}

这将输出:5e-0000006

我仍然想知道为什么我不使用JRaw。。。

由于您想要一个精确的字符串,并且您实际拥有的json是一个数字(这意味着5e-0000006将等于5e-6),我建议使用regex:

string json = "{"myfield":5e-0000006}";
Regex regex = new Regex("(?<=:)[^}]+");
string result = regex.Match(json).Value;

解释

(?<=:)查找冒号(:)

[^}]+匹配任何不是右大括号的字符(})一次或多次。

这将为您提供一个精确字符串形式的值。

更新

如果您想基于myfield变量进行匹配,可以扩展正则表达式以包含以下信息:

string json = "{"myfield":5e-0000006}";
Regex regex = new Regex("(?<="myfield":)[^}]+");
string result = regex.Match(json).Value;

现在,您将只得到前面有"myfield"的行,以防您有许多行。

当然,您可以用一个变量来替换"myfield",比如:

string json = "{"myfield":5e-0000006}";
string myvar = "myfield";
Regex regex = new Regex("(?<="" + myvar + "":)[^}]+");
string result = regex.Match(json).Value;

我最终围绕System.Text.Json 创建了一个简单的包装器

class MyJToken {
JsonElement cur;
string fieldName;
public bool IsNull { get; private set; }
public MyJToken(JsonElement cur, string fieldName) {
this.cur = cur;
this.fieldName = fieldName;
}
public MyJToken() {
IsNull = true;
}
public override string ToString() {
if (IsNull) {
return "null";
}
return cur.ToString();
}
public static MyJToken Parse(string json) {
JsonDocument doc = JsonDocument.Parse(json);
return new MyJToken(doc.RootElement, "root");
}
public IEnumerable<(string, MyJToken)> EnumKeyVal() {
foreach(var elem in cur.EnumerateObject()) {
yield return (elem.Name, new MyJToken(elem.Value, elem.Name));
}
yield break;
}
public IEnumerable<MyJToken> EnumList() {
foreach (var elem in cur.EnumerateArray()) {
yield return new MyJToken(elem, "");
}
yield break;
}
public MyJToken get(string name) {
return this[name];
}
public MyJToken this[string key] {
get {
if (!cur.TryGetProperty(key, out var value))
return new MyJToken();
return new MyJToken(value, key);
}
}
public MyJToken this[int key] {
get => new MyJToken(cur[key], key.ToString());
}
void SayNotFound() {
throw new Exception($"Filed {fieldName} not found");
}
public string STR() {
if (IsNull) SayNotFound();
return cur.GetString();
}
public string STR(string def) {
if (IsNull) return def;
return STR();
}
public string RAW() {
if (IsNull) SayNotFound();
return cur.GetRawText();
}
public string RAW(string def) {
if (IsNull) return def;
return RAW();
}
public decimal DEC() {
if (IsNull) SayNotFound();
return cur.GetDecimal();
}
public decimal DEC(decimal def) {
if (IsNull) return def;
return DEC();
}
public long LONG() {
if (IsNull) SayNotFound();
return cur.GetInt64();
}
public long LONG(long def) {
if (IsNull) return def;
return LONG();
}
}

现在我可以得到我想要的任何东西:

var json = "{"myfield":5e-0000006}";
var root = MyJToken.Parse(json);
var tok = root["myfield"];
Console.WriteLine($"num={tok.DEC()} raw={tok.RAW()}");

相关内容

  • 没有找到相关文章

最新更新