Twitch API: как получить _links?

я использую Twitch API для своего проекта, и мне нужно получить значение _links на: https://api.twitch.tv/kraken/streams/ogaminglol (пример)

Я использую этот код:

WebClient strJson = new WebClient();
string test = strJson.DownloadString("https://api.twitch.tv/kraken/streams/ogaminglol");
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Streams));
MemoryStream ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(test));
Streams stream = (Streams)js.ReadObject(ms);
//label1.Text = "Title : " + stream.game;
ms.Close();

И мой класс Streams, который получает данные

[DataContract]
class Streams
{
    [DataMember]
    public Dictionary<string, string> _links { get; set; }

    [DataMember]
    public string self { get; set; }

    [DataMember]
    public string channel { get; set; }

    [DataMember]
    public Stream stream { get; set; }
}

Я и канал пусты, потому что в https://api.twitch.tv/kraken/streams/ogaminglol они находятся в разделе "_links". Я пробовал словарь, но не увенчался успехом. Надеюсь, вы понимаете мою проблему (и мой английский: p).


person Froelicher    schedule 07.02.2015    source источник


Ответы (1)


Здесь есть несколько проблем, некоторые из которых могут вызывать симптомы, которые вы описываете:

  1. Ваша модель данных не соответствует модели JSON. self является свойством _links, а не Streams. channel появляется как свойство в _links и stream, а не Streams.

  2. Ваш класс Streams включает свойство DataMember Stream, который является абстрактным классом. Конечно, это не может быть десериализовано. Может быть, вы забыли включить это в свой вопрос?

  3. Ваш словарь _links имеет «простой» формат словаря, т. е. DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true. Вам необходимо использовать этот параметр (только для .Net 4.5 или более поздней версии) или переключиться на JavaScriptSerializer или Json.NET.

  4. Вы используете кодировку ASCII, который ограничен младшими 128 символами Unicode. Используйте Encoding.Unicode вместо этого.

  5. WebClient является одноразовым поэтому должен быть создан внутри инструкции using.

Чтобы исправить это, вам необходимо:

  1. Перейдите на сайт http://json2csharp.com/, опубликуйте свой JSON, и он сгенерирует для вас классы, а затем преобразуйте все свойства _links в public Dictionary<string, string> _links { get; set; }. Вы должны получить это:

    public class Streams
    {
        public Dictionary<string, string> _links { get; set; }
    
        public Stream stream { get; set; }
    }
    
    public class Stream
    {
        public long _id { get; set; }
        public string game { get; set; }
        public int viewers { get; set; }
        public string created_at { get; set; }
        public Dictionary<string, string> _links { get; set; }
        public Preview preview { get; set; }
        public Channel channel { get; set; }
    }
    
    public class Channel
    {
        public Dictionary<string, string> _links { get; set; }
        public object background { get; set; }
        public object banner { get; set; }
        public string broadcaster_language { get; set; }
        public string display_name { get; set; }
        public string game { get; set; }
        public string logo { get; set; }
        public bool mature { get; set; }
        public string status { get; set; }
        public bool partner { get; set; }
        public string url { get; set; }
        public string video_banner { get; set; }
        public int _id { get; set; }
        public string name { get; set; }
        public string created_at { get; set; }
        public string updated_at { get; set; }
        public int delay { get; set; }
        public int followers { get; set; }
        public string profile_banner { get; set; }
        public string profile_banner_background_color { get; set; }
        public int views { get; set; }
        public string language { get; set; }
    }
    
    public class Preview
    {
        public string small { get; set; }
        public string medium { get; set; }
        public string large { get; set; }
        public string template { get; set; }
    }
    
  2. Сделав это, вы можете немедленно десериализовать свой JSON, используя либо JavaScriptSerializer, либо Json.NET:

        string test;
        using (WebClient strJson = new WebClient())
        {
            test = strJson.DownloadString("https://api.twitch.tv/kraken/streams/ogaminglol");
        }
    
        var streams1 = JsonConvert.DeserializeObject<Streams>(test);
    
        var streams2 = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Streams>(test);
    

    В обоих случаях вы увидите содержимое словаря.

  3. Если вы хотите использовать DataContractJsonSerializer и работаете в .Net 4.5 или более поздней версии, вам понадобятся следующие вспомогательные методы:

    private static MemoryStream GenerateStreamFromString(string value)
    {
        return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
    }
    
    public static T GetObject<T>(string json) where T : class
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
        return GetObject<T>(json, serializer);
    }
    
    public static T GetObject<T>(string json, DataContractJsonSerializerSettings settings) where T : class
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
        return GetObject<T>(json, serializer);
    }
    
    public static T GetObject<T>(string json, DataContractJsonSerializer serializer)
    {
        using (var stream = GenerateStreamFromString(json))
        {
            return (T)serializer.ReadObject(stream);
        }
    }
    

    затем назовите это так:

        var streams3 = DataContractJsonSerializerHelper.GetObject<Streams>(test, new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });
    
person dbc    schedule 08.02.2015