У меня есть 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
Я пытаюсь уменьшить количество классов, которые я должен сделать, чтобы выполнить это требование схемы JSON, и мне действительно не нужны остальные поля каждого типа. Кстати, это Telegram Bot API, попробуйте посетить страницу API, см. «Доступные типы», он огромен и очень-очень вложен (по крайней мере, для меня)





Вы можете использовать сеттеры с поддержкой приватных полей:
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; }
}
}
Ясно, никогда не думал, что setter можно использовать таким образом, но, к сожалению, это требует резервного значения. Тем не менее, мне не пришлось создавать отдельный конвертер
еще один, могу ли я сделать что-то вроде value.MIME = MIMEType.Video, а затем сделать _video = value, или я могу сделать это только с резервным значением после назначения value на back-val?
Вы можете использовать Dictionary<string, object> вместо класса APIFile. Затем вы можете добавить FileMIME в каждый словарь перед возвратом ответа.
Почему бы не сделать
APIFileабстрактным базовым классом и создать подклассыAPIPhoto,APIVideo,APIDocumentи так далее?