С# Десериализовать строку Json из Quandl

Я потратил несколько часов на это и до сих пор не могу найти ответ. У меня есть строка Json, которую мне нужно десериализовать. Это должно быть просто, но я получаю следующее сообщение об ошибке:

При синтаксическом анализе значения обнаружен неожиданный символ: Q. Путь '', строка 0, позиция 0.

Моя строка json следующая:

https://www.quandl.com/api/v1/datasets/FRED/GDP.json?auth_token=Mi1xP1q2776TU4kmGcHo&collapse=monthly&transformation=none&sort_order=asc&rows=100

Это ссылка на строку Json, предоставленную онлайн-базой данных Quandl.

Я использовал следующий веб-сайт:

http://json2csharp.com/

для создания необходимого класса.

Я понимаю, что тогда мне придется десериализоваться в этот класс, используя:

var result = JsonConvert.DeserializeObject<List<RootObject>>(request.jsonString);

Но это не работает.

Вот мой полный код:

    public class Errors
    {
    }

    public class RootObject
    {
        public Errors errors { get; set; }
        public int id { get; set; }
        public string source_name { get; set; }
        public string source_code { get; set; }
        public string code { get; set; }
        public string name { get; set; }
        public string urlize_name { get; set; }
        public string display_url { get; set; }
        public string description { get; set; }
        public string updated_at { get; set; }
        public string frequency { get; set; }
        public string from_date { get; set; }
        public string to_date { get; set; }
        public List<string> column_names { get; set; }
        public bool @private { get; set; }
        public object type { get; set; }
        public bool premium { get; set; }
        public List<List<object>> data { get; set; }
    }
    private void PullFromQuandl()
    {
        QuandlDownloadRequest request = new QuandlDownloadRequest();
        request.APIKey = "Mi1xP1q2776TU4kmGcHo";
        request.Datacode = new Datacode("FRED", "GDP");
        request.Format = FileFormats.JSON;
        request.Frequency = Frequencies.Monthly;
        request.Truncation = 100;
        request.Sort = SortOrders.Ascending;

        string jsonString = request.ToRequestString();

        var result = JsonConvert.DeserializeObject<List<RootObject>> (jsonString);
        }

person user5245113    schedule 20.09.2015    source источник


Ответы (3)


Вы можете пометить это как ответ, потому что то, что вы разместили в качестве ответа, можно было бы сделать гораздо проще, взглянув на quandl api:

using QuandlCS.Connection; // need to use this

а потом

QuandlConnection conn = new QuandlConnection ();
string json = conn.Request(request); // request is your QuandlDownloadRequst
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);

это то же самое, что и в вашем ответе. у них есть класс для этого :D

для получения дополнительной информации см. их документы C# API: https://github.com/HubertJ/QuandlCS

person x4rf41    schedule 20.09.2015
comment
Хорошо сыграно, сэр. Намного проще. Любая идея, как я могу привязать этот объект к datagridview? - person user5245113; 20.09.2015
comment
dgvPending.Datasource = obj; - person user5245113; 20.09.2015
comment
источник данных должен быть типа коллекции (список и т. д.). Вы можете попробовать dgv.DataSource = obj.data. но я почти уверен, что это не сработает. поэтому либо вручную перебирайте obj.data и используйте dgvPending.Rows.Add(), либо каким-то образом сделайте правильныйList<SomeClass> из массива data (вручную), а затем поместите его как DataSource - person x4rf41; 20.09.2015
comment
Я просто повторю вручную с помощью dgvPending.Rows.Add(). Кажется проще. Но как извлечь строку? Я не могу понять это. - person user5245113; 20.09.2015
comment
foreach(List<object> item in obj.data) { dgv.Rows.Add(item[0],item[1]); } было бы неплохо начать - person x4rf41; 20.09.2015
comment
Пробовал, но постоянно выдает сообщение об ошибке. Будет продолжать попытки. - person user5245113; 20.09.2015
comment
Я заработал. Спасибо x4rf41. Вы действительно помогли. Есть ли другой способ, которым я могу проголосовать за вас? Я бы послал тебе денег, если бы мог, без шуток. По сути, это означает, что я могу отображать любой набор данных из Quandl прямо в приложении (обменные курсы, цифры ВВП и т. д.). Мой босс будет счастлив. Спасибо, что нашли время. код был таким: dgvPending.Columns.Add(Name, Date); dgvPending.Columns.Add(Имя, Ставка); foreach (List‹object› элемент в obj.data) { dgvPending.Rows.Add(item[0], item[1]); } - person user5245113; 20.09.2015
comment
это прекрасный человек, мне в основном платят за это, потому что я на работе и мне больше нечего делать :D - person x4rf41; 20.09.2015
comment
Ха-ха, и я работаю сверхурочно бесплатно. Так что я думаю, что это идет полный круг. Здорово, так держать. Я надеюсь, что когда-нибудь стану таким же хорошим, как ты. - person user5245113; 20.09.2015

Строка действительно является строкой json. Спасибо за ссылку, которую вы предоставили. Я совершил глупую ошибку. Квандл возвращал ссылку на строку. Поэтому я использовал HttpWebRequest для получения самой строки. Затем я отредактировал десериализацию, как вы предлагаете. Я думаю, это сработало. Теперь проблема в том, что он не привязан к моему datagridview.

        private void PullFromQuandl()
       {
        QuandlDownloadRequest request = new QuandlDownloadRequest();
        request.APIKey = "Mi1xP1q2776TU4kmGcHo";
        request.Datacode = new Datacode("CURRFX", "EURUSD");
        request.Format = FileFormats.JSON;
        request.Frequency = Frequencies.Monthly;
        request.Truncation = 100;
        request.Sort = SortOrders.Ascending;
        string jsonString = request.ToRequestString();

        HttpWebRequest request2 = null;
        HttpWebResponse response = null;
        string returnData = string.Empty;
        request2 = (HttpWebRequest)System.Net.WebRequest.Create(new Uri(jsonString));
        request2.Method = "GET";
        response = (HttpWebResponse)request2.GetResponse();

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        returnData = reader.ReadToEnd();
        var result = JsonConvert.DeserializeObject<RootObject>(returnData);
        dgvPending.DataSource = result;
        }
person user5245113    schedule 20.09.2015
comment
посмотрите на ответ, который я только что опубликовал, вы могли бы сделать это намного проще: D - person x4rf41; 20.09.2015

Прежде всего: избегайте типа объекта. Сериализаторы JSON -> Десериализаторы обычно имеют проблемы с этим.

Второй:

JsonConvert.DeserializeObject<List<RootObject>> (jsonString);

вы пытаетесь десериализовать массив RootObject. но предоставленный json содержит только один. так должно быть:

JsonConvert.DeserializeObject<RootObject> (jsonString);

В третьих:

string jsonString = request.ToRequestString();

можете ли вы выполнить отладку и посмотреть, действительно ли jsonString содержит действительный json (используйте http://jsonlint.org/). Мне кажется, вам понадобится строка response, а не строка запроса. (Я думаю, именно поэтому вы получаете сообщение об ошибке!!!)

Четвертое:

скорее всего будет больше ошибок. Я немного сомневаюсь, что десериализатор json с настройками по умолчанию сможет правильно декодировать массив данных. но List<List<object>> стоит попробовать. если это дает ошибку, попробуйте List<List<string>> вместо этого. если это не сработает, вам, вероятно, придется делать это вручную.

Проверьте json с помощью отладчика. я думаю, что вы пытаетесь десериализовать НЕ то, что вы разместили здесь!

также: из какой библиотеки вы используете это: JsonConvert.DeserializeObject?

Пятое:

кто, черт возьми, разработал свой API для создания такого json:

[
        [
            "1947-01-31",
            243.1
        ]
]

это просто отсталый (я просто должен был это сказать)

person x4rf41    schedule 20.09.2015
comment
но я был прав, что ваш jsonString был неправильным? - person x4rf41; 20.09.2015
comment
Или, по крайней мере, я так думаю. Сейчас выложу код. - person user5245113; 20.09.2015
comment
я посмотрел на класс API, и ToRequestString просто возвращает URL-адрес, необходимый для вызова API. вам все еще нужно сделать вызов API - person x4rf41; 20.09.2015
comment
Я использую библиотеку Newtonsoft.Json и API QuandlCS. - person user5245113; 20.09.2015