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

时间:2018-02-03 06:30:58

标签: c# json json.net

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

   lblResult.Text=test.quotes.USDSGD.ToString();

但我想要的是无论用户选择的货币如何都能获得结果。另一个总是美元,所以我想将它和用户输入货币结合起来从API中获取正确的值,如:

var propertyName = "USD" + destinationCurrencyName; // "USDSGD"
lblResult.Text=test.quotes.{propertyName}; // what I'd like

在这里,我将访问该物业" USDSGD"。

我知道我可以使用反射(Get property value from string using reflection in C#),但这似乎有点矫枉过正。

这是查询返回的内容:

{
  "success":true,
  "terms":"https:\/\/currencylayer.com\/terms",
  "privacy":"https:\/\/currencylayer.com\/privacy",
  "timestamp":1517629571,
  "source":"USD",
  "quotes":{
    "USDSGD":1.318504
  }
}

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

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

目前我的代码

var test2 = JsonConvert.DeserializeObject<dynamic>(resString);
        lblResult.Text = test2.quotes.USD+convertTo;

返回值:

  

SGD

自&#34; convertTo&#34;变量恰好是&#34; SGD&#34;。

我希望代码执行lblResult.Text = test2.quotes.USD+convertTo;而不是返回我&#34; convertTo&#34;变量

2 个答案:

答案 0 :(得分:3)

现在,我理解了您的问题,您正在尝试连接字符串以访问值,而不是连接值和货币。

使用dynamic无法做到这一点,并且没有必要。反序列化为JObject并使用其属性来获取值:

var test2 = JObject.Parse(resString);
var value = (test2[“quotes”] as JObject)[“USD” + convertTo];

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

答案 1 :(得分:1)

您需要使用JObject来浏览响应对象:

var response = JObject.Parse(resString);
var quotes = response["quotes"];
lblResult.Text = quotes[ "USD" + convertTo ].Value<string>().ToString();

JObject的索引器允许您直接按字符串索引,这使您能够动态选择用户想要的正确属性。