diff --git a/AsbCloudApp/Data/GTR/JsonValue.cs b/AsbCloudApp/Data/GTR/JsonValue.cs new file mode 100644 index 00000000..cd37abea --- /dev/null +++ b/AsbCloudApp/Data/GTR/JsonValue.cs @@ -0,0 +1,14 @@ +namespace AsbCloudApp.Data.GTR +{ + /// + /// Класс позволяющий хранить значение неопределенного типа. + /// Все возможные типы должны быть описаны в JsonValueJsonConverter. + /// + /// + public record JsonValue(object Value) + { + /// + public override string ToString() + => Value.ToString() ?? string.Empty; + } +} diff --git a/AsbCloudApp/Data/GTR/WitsFloatDto.cs b/AsbCloudApp/Data/GTR/WitsFloatDto.cs deleted file mode 100644 index 4867a566..00000000 --- a/AsbCloudApp/Data/GTR/WitsFloatDto.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace AsbCloudApp.Data.GTR -{ - /// - /// класс для получения данных ГТИ с значением типа float - /// - public class WitsFloatDto : ITelemetryData - { - /// - public DateTime DateTime { get; set; } - /// - public int IdTelemetry { get; set; } - /// - /// ИД рекорда согласно спецификации WITS - /// - public int IdRecord { get; set; } - /// - /// ИД элемента рекорда согласно спецификации WITS - /// - public int IdItem { get; set; } - /// - public float? Value { get; set; } - } -} diff --git a/AsbCloudApp/Data/GTR/WitsIntDto.cs b/AsbCloudApp/Data/GTR/WitsIntDto.cs deleted file mode 100644 index a8001172..00000000 --- a/AsbCloudApp/Data/GTR/WitsIntDto.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace AsbCloudApp.Data.GTR -{ - /// - /// класс для получения данных ГТИ с значением типа int16 int32 - /// - public class WitsIntDto - { - /// - public DateTime DateTime { get; set; } - /// - public int IdTelemetry { get; set; } - /// - /// ИД рекорда согласно спецификации WITS - /// - public int IdRecord { get; set; } - /// - /// ИД элемента рекорда согласно спецификации WITS - /// - public int IdItem { get; set; } - /// - public int? Value { get; set; } - } -} diff --git a/AsbCloudApp/Data/GTR/WitsRecordDto.cs b/AsbCloudApp/Data/GTR/WitsRecordDto.cs new file mode 100644 index 00000000..28e6ba81 --- /dev/null +++ b/AsbCloudApp/Data/GTR/WitsRecordDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +namespace AsbCloudApp.Data.GTR +{ + /// + /// Запись WITS + /// + public class WitsRecordDto + { + /// + /// Id записи + /// + public int Id { get; set; } + + /// + /// Дата создания записи + /// + public DateTime Date { get; set; } + + /// + /// Параметры. Ключ - id_item. ValueContainer содержит значение. + /// + public Dictionary Items { get; set; } = new(); + } +} diff --git a/AsbCloudApp/Data/GTR/WitsStrDto.cs b/AsbCloudApp/Data/GTR/WitsStrDto.cs deleted file mode 100644 index 69b41e9c..00000000 --- a/AsbCloudApp/Data/GTR/WitsStrDto.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace AsbCloudApp.Data.GTR -{ - /// - /// класс для получения данных ГТИ с значением типа string - /// - public class WitsStrDto : WitsBaseDto - { - /// - public DateTime DateTime { get; set; } - /// - public int IdTelemetry { get; set; } - /// - /// ИД рекорда согласно спецификации WITS - /// - public int IdRecord { get; set; } - /// - /// ИД элемента рекорда согласно спецификации WITS - /// - public int IdItem { get; set; } - /// - public string? Value { get; set; } - } -} diff --git a/AsbCloudWebApi/Converters/ValueContainerJsonConverter.cs b/AsbCloudWebApi/Converters/ValueContainerJsonConverter.cs new file mode 100644 index 00000000..386f1234 --- /dev/null +++ b/AsbCloudWebApi/Converters/ValueContainerJsonConverter.cs @@ -0,0 +1,74 @@ +using System; +using System.Globalization; +using System.Text.Json.Serialization; +using System.Text.Json; +using AsbCloudApp.Data.GTR; + +namespace AsbCloudWebApi.Converters +{ + public class JsonValueJsonConverter : JsonConverter + { + public override JsonValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var stringVal = reader.GetString() ?? string.Empty; + return new JsonValue(stringVal); + } + + if (reader.TokenType == JsonTokenType.Number) + { + if (reader.TryGetInt32(out int intVal)) + return new JsonValue(intVal); + + if (reader.TryGetDouble(out double doubleVal)) + return new JsonValue((float)doubleVal); + } + + throw new FormatException($"Wrong format at position {reader.Position}"); + } + + public override void Write(Utf8JsonWriter writer, JsonValue value, JsonSerializerOptions options) + { + if (value.Value is string strValue) + { + writer.WriteStringValue(FormatString(strValue)); + return; + } + + if (value.Value is int intValue) + { + writer.WriteNumberValue(intValue); + return; + } + + if (value.Value is short shortValue) + { + writer.WriteNumberValue(shortValue); + return; + } + + if (value.Value is float floatValue) + { + writer.WriteRawValue(floatValue.ToString("#0.0##", CultureInfo.InvariantCulture), true); + return; + } + + if (value.Value is double doubleValue) + { + writer.WriteRawValue(doubleValue.ToString("#0.0##", CultureInfo.InvariantCulture), true); + return; + } + + var typeName = value.Value.GetType().Name; + throw new NotImplementedException($"{typeName} is not supported type for WITS value"); + } + + private static string FormatString(string value) + => value + .Replace("\"", "") + .Trim() + .Replace("\r", "") + .Replace("\n", ""); + } +} diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index 14d8db0f..7399a68e 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -22,13 +22,14 @@ namespace AsbCloudWebApi public void ConfigureServices(IServiceCollection services) { services.AddControllers() - .AddJsonOptions(new System.Action(options => + .AddJsonOptions(new System.Action(options => { options.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals | System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString; options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter()); + options.JsonSerializerOptions.Converters.Add(new JsonValueJsonConverter()); })) .AddProtoBufNet();