Как избавиться от ветки if else при десериализации
В программу приходят запросы из внешней среды, тип запроса я узнаю исходя из поля type, как написать данный код в объектно-ориентированном стиле, и возможно ли это?
public IMessage ConvertJsonToObject(string request)
{
if (request.Contains(@"""type"":""recognitionResult"""))
return JsonSerializer.Deserialize<RecognitionResult>(request);
else if (request.Contains(@"""type"":""photo"""))
return JsonSerializer.Deserialize<PhotoOnRequest>(request);
else if (request.Contains(@"""type"":""requestCurrentPhoto"""))
return JsonSerializer.Deserialize<PhotoRequest>(request);
else if (request.Contains(@"""type"":""requestPhoto"""))
return JsonSerializer.Deserialize<DateTimePhotoRequest>(request);
else if (request.Contains(@"""type"":""recognitionChanStatus"""))
return JsonSerializer.Deserialize<StatusChannel>(request);
else if (request.Contains(@"""type"":""recognitionKeyStatus"""))
return JsonSerializer.Deserialize<StatusSecurityKey>(request);
else if (request.Contains(@"""type"":""recognitionVideoStatus"""))
return JsonSerializer.Deserialize<StatusVideo>(request);
else
_logger.WriteToExceptionLog(
new Exception($"Не удалось десериализовать входящее сообщение {request}"));
return null;
}
Пример запроса:
/// <summary>
/// Запрос текущей фотографии
/// </summary>
public class PhotoRequest : IMessage
{
/// <summary>
/// Идентификатор камеры
/// </summary>
public string camera { get; set; }
/// <summary>
/// Название и версия протокола
/// </summary>
public string protocol { get; set; }
/// <summary>
/// Тип сообщения
/// </summary>
public string type { get; set; }
public string GetJson()
{
return JsonConvert.SerializeObject(this);
}
public virtual string GetLogInfo(TransferType transferType, string address)
{
return $"{transferType}: {type}," +
$" Адрес: {address}," +
$" Камера: {camera}," +
$" Время создания запрашиваемого фото: {DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff")}";
}
}
Пример сериализованного запроса:
{"camera":"Context1","protocol":"protocol1","type":"requestCurrentPhoto"}
Ответы (1 шт):
Автор решения: aepot
→ Ссылка
Определять тип лучше с помощью десереализации в модель, которая подходит под все типы сообщений.
Как-то так получится.
public class MessageTypeModel
{
[JsonPropertyName("type")]
public string Type { get; set; }
}
public Type GetMessageType(string json)
{
return JsonSerializer.Deserialize<MessageTypeModel>(json).Type switch
{
"recognitionResult" => typeof(RecognitionResult),
"photo" => typeof(PhotoOnRequest),
"requestCurrentPhoto" => typeof(PhotoRequest),
"requestPhoto" => typeof(DateTimePhotoRequest),
"recognitionChanStatus" => typeof(StatusChannel),
"recognitionKeyStatus" => typeof(StatusSecurityKey),
"recognitionVideoStatus" => typeof(StatusVideo),
_ => throw new Exception($"Не удалось десериализовать входящее сообщение {json}")
};
}
public IMessage ConvertJsonToObject(string request)
{
try
{
return (IMessage)JsonSerializer.Deserialize(request, GetMessageType(request));
}
catch (Exception ex)
{
_logger.WriteToExceptionLog(ex);
}
return null;
}