JSON不同的名字

时间:2017-10-17 15:20:49

标签: c# .net json

目前,我正在为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/

谢谢!

2 个答案:

答案 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