2014-10-23 3 views
0

Я пытаюсь десериализовать ответ JSon из webservice, но я не знаю, как это сделать.Deserializing Json с индексом

Существует пример:

{ 
    "0": { 
     "course_info": { 
      "course_id": 3, 
      "code": "", 
      "course_name": "Fiches Docebo", 
      "course_description": "<p>Fiches pratiques Docebo<\/p>", 
      "status": "2", 
      "selling": "0", 
      "price": "", 
      "subscribe_method": "2", 
      "course_edition": "0", 
      "course_type": "elearning", 
      "sub_start_date": "", 
      "sub_end_date": "", 
      "date_begin": "0000-00-00", 
      "date_end": "0000-00-00", 
      "course_link": "" 
     } 
    }, 
    "1": { 
     "course_info": { 
      "course_id": 5, 
      "code": "prout", 
      "course_name": "Prout", 
      "course_description": "<p style=\"text-align: justify;\">Prout<\/p>", 
      "status": "2", 
      "selling": "0", 
      "price": "", 
      "subscribe_method": "2", 
      "course_edition": "0", 
      "course_type": "elearning", 
      "sub_start_date": "", 
      "sub_end_date": "", 
      "date_begin": "0000-00-00", 
      "date_end": "0000-00-00", 
      "course_link": "" 
     } 
    }, 
    "success": true 
} 

Первый узел является индексом, и мне не удастся десериализовать это без declarate один за другим номерам ...

я стараюсь, как это:

public class ListCoursesResponse 
{ 
    public bool? success { get; set; } 
    public Dictionary<String,Course> courses { get; set; } 
} 

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

Я не знаю, как объяснить RestSharp первых узлов являются числами, которые являются 1, 2, 3 до последнего узла ...

Может быть, мне нужно кодировать конкретный десериализатор, но я не знаю, как ..

Я использую десериализатор RestSharp.

EDIT: есть класс, конечно

[DeserializeAs(Name = "course_info")]  
public class Course 
{ 
    [DeserializeAs(Name = "course_id")] 
    public long? Id { get; set; } 
    [DeserializeAs(Name = "course_name")] 
    public string Name { get; set; } 
    public string Code { get; set; } 
    [DeserializeAs(Name = "course_description")] 
    public string Description { get; set; } 
    [DeserializeAs(Name = "course_edition")] 
    public Boolean? IsEditable { get; set; } 
    [DeserializeAs(Name = "course_link")] 
    public string Url { get; set; } 
    [DeserializeAs(Name = "course_type")] 
    public string Type { get; set; } 
    [DeserializeAs(Name = "date_begin")] 
    public string BeginDate { get; set; } 
    [DeserializeAs(Name = "date_end")] 
    public string EndDate { get; set; } 
    public string Price { get; set; } 
    [DeserializeAs(Name = "selling")] 
    public Boolean? IsSalable { get; set; } 
    public int? Status { get; set; } 
    [DeserializeAs(Name = "sub_start_date")] 
    public string SubscriptionStartDate { get; set; } 
    [DeserializeAs(Name = "sub_end_date")] 
    public string SubscriptionStopDate { get; set; } 
    [DeserializeAs(Name = "subscribe_method")] 
    public int? SubscriptionMethod { get; set; } 
} 

EDIT 2: Существует, как я называю библиотеке

public ListCoursesResponse ListCourses(int? categoryId = null) 
{ 
    if (categoryId != null) 
    { 
     List<KeyValuePair<String, Object>> list = new List<KeyValuePair<string, object>>(); 
     list.Add(new KeyValuePair<String, Object>("category", categoryId)); 
     return Execute<ListCoursesResponse>(String.Format("{0}/{1}", _course, "listCourses"), list.ToArray()); 
    } 

    return Execute<ListCoursesResponse>(String.Format("{0}/{1}", _course, "listCourses")); 
} 

public T Execute<T>(string resource, params KeyValuePair<String, Object>[] parameters) where T : new() 
{ 
    var client = new RestClient(); 

    client.AddHandler("text/html", new RestSharp.Deserializers.JsonDeserializer()); 

    client.BaseUrl = DoceboApiUrl; 

    var requestUrl = DoceboApiUrl; 
    if (!requestUrl.EndsWith("/")) 
     requestUrl += "/"; 

    requestUrl += resource; 

    var req = new RestRequest(RestSharp.Method.POST); 
    req.Resource = resource; 

    // Parameters Management 
    if (parameters != null) 
     foreach (KeyValuePair<String, Object> kvp in parameters) 
      req.AddParameter(new Parameter() { Name = kvp.Key, Value = kvp.Value, Type = ParameterType.GetOrPost }); 

    client.Authenticator = new DoceboAuthenticator(ApiKey, ApiSecret, req.Parameters); 

    var response = client.Execute<T>(req); 

    if (response.ErrorException != null) 
    { 
     const string message = "Error retrieving response. Check inner details for more info."; 
     throw new ApplicationException(message, response.ErrorException); 
    } 

    return response.Data; 
} 
+2

Вы можете разместить класс курс? –

+0

Существует код класса. – BaptX

ответ

0

прокси-классы (ListCoursesResponse является writed, как вы хотели, остальное генерируется из JSON с json2csharp.com):

public class ListCoursesResponse 
{ 
    public bool? success { get; set; } 
    public Dictionary<String, Course> courses { get; set; } 
} 

public class Course 
{ 
    public CourseInfo course_info { get; set; } 
} 

public class CourseInfo 
{ 
    public int course_id { get; set; } 
    public string code { get; set; } 
    public string course_name { get; set; } 
    public string course_description { get; set; } 
    public string status { get; set; } 
    public string selling { get; set; } 
    public string price { get; set; } 
    public string subscribe_method { get; set; } 
    public string course_edition { get; set; } 
    public string course_type { get; set; } 
    public string sub_start_date { get; set; } 
    public string sub_end_date { get; set; } 
    public string date_begin { get; set; } 
    public string date_end { get; set; } 
    public string course_link { get; set; } 
} 

Десериализация:

var parsed = JObject.Parse(input); 
var result = new 
    ListCoursesResponse 
     { 
      success = parsed["success"].Value<bool?>(), 
      courses = 
       parsed.Properties() 
         .Where(prop => prop.Name != "success") 
         .ToDictionary(prop => prop.Name, 
            prop => prop.Value.ToObject<Course>()) 
     }; 
+0

Я отредактирую свое сообщение, чтобы поставить метод вызова. На данный момент все сериализуется/десериализуется библиотекой, без моего кода. – BaptX

+0

Как сделать, если мне не нужен индекс, но только список курсов? – BaptX

+0

Мне очень жаль, но десериализатор использует RestSharp, а не JSon.NET. – BaptX

0

Я уверен, что это самый худший способ справиться с этой просьбой, но вот мое отвратительное решение:

public ListCoursesResponse ListCourses(int? categoryId = null) 
{ 
    Dictionary<String, Object> dico = null; 

    if (categoryId != null) 
    { 
     List<KeyValuePair<String, Object>> list = new List<KeyValuePair<string, object>>(); 
     list.Add(new KeyValuePair<String, Object>("category", categoryId)); 
     dico = Execute<Dictionary<String, Object>>(String.Format("{0}/{1}", _course, "listCourses"), list.ToArray()); 
    } 

    dico = Execute<Dictionary<String, Object>>(String.Format("{0}/{1}", _course, "listCourses")); 

    return dicoToResponse(dico); 
} 

И:

private ListCoursesResponse dicoToResponse(Dictionary<String, Object> dico) 
    { 
     ListCoursesResponse coursesResponse = new ListCoursesResponse(); 

     coursesResponse.success = (Boolean)dico.First(x => x.Key == "success").Value; 

     if (coursesResponse.success == true) 
     { 
      dico.Remove("success"); 
      foreach (Dictionary<String, Object> v in dico.Values) 
      { 
       Course course = new Course(); 

       Dictionary<String, Object> values = (Dictionary<String, Object>)v["course_info"]; 
       foreach (String key in values.Keys) 
       { 
        switch (key) 
        { 
         case "course_id" : 
          course.Id = (long)values[key]; 
          break; 
         case "code": 
          course.Code = (string)values[key]; 
          break; 
         case "course_name" : 
          course.Name = (string)values[key]; 
          break; 
         case "course_description" : 
          course.Description = (string)values[key]; 
          break; 
         case "status" : 
          course.Status = (string)values[key]; 
          break; 
         case "selling" : 
          course.IsSalable = (string)values[key] == "0" ? false : true; 
          break; 
         case "price" : 
          course.Price = (string)values[key]; 
          break; 
         case "subscribe_method" : 
          course.SubscriptionMethod = (string)values[key]; 
          break; 
         case "course_edition" : 
          course.IsEditable = (string)values[key] == "0" ? false : true; 
          break; 
         case "course_type" : 
          course.Type = (string)values[key]; 
          break; 
         case "sub_start_date" : 
          course.SubscriptionStartDate = (string)values[key]; 
          break; 
         case "sub_end_date" : 
          course.SubscriptionEndDate = (string)values[key]; 
          break; 
         case "date_begin" : 
          course.BeginDate = (string)values[key]; 
          break; 
         case "date_end" : 
          course.EndDate = (string)values[key]; 
          break; 
         case "course_link" : 
          course.Url = (string)values[key]; 
          break; 
        } 
       } 

       coursesResponse.courses.Add(course); 
      } 
     } 

return coursesResponse; 
}