目前,我正在为API编写C#包装器。然而,它需要货币,美元,英镑等,并转换所提供货币的数据。执行此操作时,它还会更改某些返回的JSON值的名称。
price_eur
price_usd
例如等。
所以我的问题是,我如何使用它来代替为几个命名差异编写数百个不同的类?我不认为JsonProperty可以解决这个问题,因为该属性需要是一个常数,这与我的经验有关。
JSON展示它的不同之处:
欧元:
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "5648.67",
"price_btc": "1.0",
"24h_volume_usd": "1847890000.0",
"market_cap_usd": "93932015864.0",
"available_supply": "16629050.0",
"total_supply": "16629050.0",
"percent_change_1h": "-0.59",
"percent_change_24h": "-1.12",
"percent_change_7d": "16.59",
"last_updated": "1508253251",
"price_eur": "4803.1770744",
"24h_volume_eur": "1571297824.8",
"market_cap_eur": "79872271729.0"
}
]
GBP:
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "5648.67",
"price_btc": "1.0",
"24h_volume_usd": "1847890000.0",
"market_cap_usd": "93932015864.0",
"available_supply": "16629050.0",
"total_supply": "16629050.0",
"percent_change_1h": "-0.59",
"percent_change_24h": "-1.12",
"percent_change_7d": "16.59",
"last_updated": "1508253251",
"price_gbp": "4276.28608281",
"24h_volume_gbp": "1398932189.27",
"market_cap_gbp": "71110575085.0"
}
]
有问题的API: https://coinmarketcap.com/api/
谢谢!
答案 0 :(得分:0)
由于更改始终相同并且遵循一致的模式,因此您可以尝试以下设计只使用一个类:
internal class CurrencyWrapper
{
public double MarketCap { get; private set; }
public static CurrencyWrapper GetWrapper(string currencyCode, string jsonString)
{
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
var instance = new CurrencyWrapper
{
MarketCap = double.Parse(values["market_cap_" + currencyCode.ToLower()])
};
return instance;
}
}
此处未包含必须在生产环境中完成的所有错误验证。
测试:
private static void Main(string[] args)
{
var eurStr = "{'market_cap_eur':'1233.22'}";
var eurWrapper = CurrencyWrapper.GetWrapper("EUR", eurStr);
var gbpStr = "{'market_cap_gbp':'123213213133.22'}";
var gbpWrapper = CurrencyWrapper.GetWrapper("GBP", gbpStr);
Console.WriteLine($"Eur market_whatever is: {eurWrapper.MarketCap}");
Console.WriteLine($"GBP market_whatever is: {gbpWrapper.MarketCap}");
Console.ReadLine();
}
通过这种方式,您可以设法使用货币代码映射属性。
答案 1 :(得分:0)
我假设您希望拥有一组属性的对象,这些属性允许您使用id和name等属性。此外,您还需要一种如何从类中读取自定义属性的机制。我的选择可能看起来有点棘手,所以请随时询问进一步的解释。
假设我们有2个json字符串:
private string input1 = "{\"id\": \"bitcoin\", \"name\": \"Bitcoin\", \"price_eur\": \"4803.1770744\"}";
private string input2 = "{\"id\": \"bitcoin\", \"name\": \"Bitcoin\", \"price_gbr\": \"4276.28608281\"}";
我们想将这些字符串转换为:
public interface IData
{
string id { get; set; }
string name { get; set; }
string price { get; }
}
我们可以这样做:
public class DynamicData : DynamicObject, IData
{
private class FakeGetMemberBinder : GetMemberBinder
{
public FakeGetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase) { }
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
throw new NotSupportedException();
}
}
public string id { get; set; }
public string name { get; set; }
public string price => GetMemberWithSufix();
public string CurrencySufix { get; set; }
private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dictionary[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames() => _dictionary.Keys;
private string GetMemberWithSufix([CallerMemberName] string callerMemberName = null)
{
var getBinder = new FakeGetMemberBinder(callerMemberName + "_" + CurrencySufix, false);
object value;
if (TryGetMember(getBinder, out value))
return value?.ToString();
throw new KeyNotFoundException();
}
}
您可以像这样使用此类:
var obj1 = JsonConvert.DeserializeObject<DynamicData>(input1);
obj1.CurrencySufix = "eur";
var obj2 = JsonConvert.DeserializeObject<DynamicData>(input2);
obj2.CurrencySufix = "gbr";
Debug.WriteLine(obj1.price);
Debug.WriteLine(obj2.price);
输出
4803.1770744
4276.28608281