#c# #json #json.net
#c# #json #json.net
Вопрос:
У меня есть JSON, в котором есть поля, которые более или менее выглядят следующим образом
{
"Photos" :
[
{
"file_id" : "Some value",
"type" : "Some certain value",
/*'Photo's specific fields*/
},
{
"file_id" : "Some value",
"type" : "Some certain value",
/*'Photo's specific fields*/
},
{
"file_id" : "Some value",
"type" : "Some certain value",
/*'Photo's specific fields*/
}
],
"Document" :
{
"file_id" : "Some value",
"type" : "Some certain value",
/*'Document's specific fields*/
},
"Video" :
{
"file_id" : "Some value",
"type" : "Some certain value",
/*'Video's specific fields*/
},
}
Где весь JSON будет десериализован в этот класс
public class APIResponse
{
[JsonProperty(PropertyName = "Photos")]
public List<APIFile> Photos;
[JsonProperty(PropertyName = "Document")]
public APIFile Document;
[JsonProperty(PropertyName = "Video")]
public APIFile Video;
}
Где APIFile
— класс, который является «целевым типом» для десериализации каждого из этих полей JSON, это выглядит следующим образом
public class APIFile
{
public enum FileMIME
{
// Some already specified enum values
}
[JsonProperty(PropertyName = "file_id")]
public string FileID;
[JsonProperty(PropertyName = "type")]
public string FileType;
[JsonIgnore()]
public FileMIME MIMEType;
}
Как вы можете видеть, эти три поля в JSON имеют некоторые общие поля, file_id
и type
, где Photos
— коллекция определенного типа, которая также имеет одни и те же общие поля.
Проблема в том, как я могу десериализовать каждое из них, но установить MIMEType
поле, соответствующее десериализованному полю? предпочтительно без использования JsonConverter
или добавления дополнительного класса
Например, при десериализации поля JSON, Document
тогда поле Document
в APIResponse
объекте будет создано с MIMEType
полем, имеющим значение MIMEType.Document
Комментарии:
1. Почему бы не сделать
APIFile
быть абстрактным базовым классом и подклассировать его какAPIPhoto
,APIVideo
,APIDocument
и так далее?2. Я пытаюсь уменьшить количество классов, которые я должен создать, чтобы выполнить это требование схемы JSON, и мне действительно не нужны остальные поля из каждого типа, это Telegram Bot API КСТАТИ, попробуйте посетить страницу API, посмотреть «Доступные типы», это огромный и очень -очень вложенный (по крайней мере, для меня)
Ответ №1:
Вы можете использовать установщики с резервными закрытыми полями:
public enum FileMIME
{
Document,
Photos,
Video
}
public class APIResponse
{
private List<APIFile> _photos;
[JsonProperty(PropertyName = "Photos")]
public List<APIFile> Photos
{
get { return _photos; }
set { _photos = value;
foreach(var photo in _photos)
{
photo.MIMEType = FileMIME.Photos;
}
}
}
private APIFile _document;
[JsonProperty(PropertyName = "Document")]
public APIFile Document
{
get { return _document; }
set { _document = value; _document.MIMEType = FileMIME.Document; }
}
private APIFile _video;
[JsonProperty(PropertyName = "Video")]
public APIFile Video
{
get { return _video; }
set { _video = value; _video.MIMEType = FileMIME.Video; }
}
}
Комментарии:
1. Понятно, никогда не думал,
set
что их можно использовать подобным образом, но для этого требуется резервное значение. Тем не менее, несмотря на это, мне не пришлось создавать отдельный конвертер2. однако еще один вопрос: могу ли я сделать что-то вроде
value.MIME = MIMEType.Video
then do_video = value
или я могу сделать это только для резервного значения послеvalue
присвоения back-val ?
Ответ №2:
Вы могли бы использовать Dictionary<string, object>
вместо класса APIFile. Затем вы можете добавить FileMIME в каждый словарь, прежде чем возвращать ответ.