考虑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()}");