Десериализация Json с индексом
Я пытаюсь десериализовать ответ 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
}
Первый узел является индексом, и мне не удается десериализовать это без объявления по одному числами...
Я пытаюсь так:
public class ListCoursesResponse
{
public bool? success { get; set; }
public Dictionary<String,Course> courses { get; set; }
}
но это не работает
Я не знаю, как объяснить RestSharp, что первые узлы - это числа от 1, 2, 3 до последнего узла...
Может быть, мне нужно кодировать определенный десериализатор, но я не знаю, как..
Я использую десериализатор RestSharp.
РЕДАКТИРОВАТЬ: есть курс класса
[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; }
}
РЕДАКТИРОВАТЬ 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 ответа
Я уверен, что это худший способ обработать этот запрос, но вот мое отвратительное решение:
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;
}
Прокси классы (ListCoursesResponse
пишется так, как вы хотели, остальные генерируются из 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>())
};