通过字符串名称从 JSON 获取属性(已反序列化为类)

Tix*_*Tix 3 c# json json.net

我正在使用https://currencylayer.com/documentation,免费帐户的货币转换 API。我让用户输入输出货币,因此例如如果用户输入 SGD,它将显示 USD 到 SGD 的货币转换:"USDSGD":1.318504 \n获取该值的方法是使用动态反序列化器,并将其放入一个标签。像这样:

\n\n
   lblResult.Text=test.quotes.USDSGD.ToString();\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我想要的是无论用户选择的货币如何都能得到结果。另一个始终是美元,因此我\xe2\x80\x99d 喜欢将其与用户输入货币结合起来,以从 API 获取正确的值,例如:

\n\n
var propertyName = "USD" + destinationCurrencyName; // "USDSGD"\nlblResult.Text=test.quotes.{propertyName}; // what I\'d like\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里我将访问属性“USDSGD”。

\n\n

我知道我可以使用反射(在 C# 中使用反射从字符串获取属性值),但这似乎有点矫枉过正。

\n\n

这是查询返回的内容:

\n\n
{\n  "success":true,\n  "terms":"https:\\/\\/currencylayer.com\\/terms",\n  "privacy":"https:\\/\\/currencylayer.com\\/privacy",\n  "timestamp":1517629571,\n  "source":"USD",\n  "quotes":{\n    "USDSGD":1.318504\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的代码 - 强类型版本确实产生了预期的结果,但我想quotes从文本框中读取货币名称(本质上是元素的属性名称):

\n\n
protected void btnConvert_Click(object sender, EventArgs e)\n{\n    string convertTo = TextBox1.Text.ToString();\n    var webRequest = (HttpWebRequest)WebRequest.Create("http://apilayer.net/api/live?access_key=MY_ACCESS_KEY&currencies=" + Server.UrlEncode(convertTo) + "&source=USD&format=1");\n    var webResponse = (HttpWebResponse)webRequest.GetResponse();\n    if (webResponse.StatusCode == HttpStatusCode.OK)\n    {\n        JavaScriptSerializer json = new JavaScriptSerializer();\n        StreamReader sr = new StreamReader(webResponse.GetResponseStream());\n        var resString = sr.ReadToEnd();\n        //var test = JsonConvert.DeserializeObject<Result>(resString);\n        //lblResult.Text=test.quotes.USDSGD.ToString();\n        var test2 = JsonConvert.DeserializeObject<dynamic>(resString);\n        lblResult.Text = test2.quotes.USD+convertTo;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

目前我的代码

\n\n
var test2 = JsonConvert.DeserializeObject<dynamic>(resString);\n        lblResult.Text = test2.quotes.USD+convertTo;\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回值:

\n\n
\n

新加坡元

\n
\n\n

由于“convertTo”变量恰好是“SGD”。

\n\n

我希望执行的代码lblResult.Text = test2.quotes.USD+convertTo;不返回“convertTo”变量。

\n

Sam*_*nen 5

现在我明白了你的问题,你\xe2\x80\x99正在尝试连接字符串来访问值,而不是连接值和货币。

\n\n

这不能完成,dynamic也没有必要。反序列化JObject并使用其属性来获取值:

\n\n
var test2 = JObject.Parse(resString);\nvar value = (test2[\xe2\x80\x9cquotes\xe2\x80\x9d] as JObject)[\xe2\x80\x9cUSD\xe2\x80\x9d + convertTo];\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,这不会检查数据是否有效。value是一个 JToken,您可以从中获取值。

\n