diff --git a/scraper/scraper.csproj b/scraper/scraper.csproj index 391f257..4dfa9a6 100644 --- a/scraper/scraper.csproj +++ b/scraper/scraper.csproj @@ -9,6 +9,7 @@ + diff --git a/scraper/src/Models/Train.cs b/scraper/src/Models/Train.cs index aa34507..54d6796 100644 --- a/scraper/src/Models/Train.cs +++ b/scraper/src/Models/Train.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using System.Text.Json; -using System.Text.Json.Serialization; using InfoferScraper.Models.Status; -using InfoferScraper.Models.Train.JsonConverters; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; namespace InfoferScraper.Models.Train { #region Interfaces @@ -89,14 +89,14 @@ namespace InfoferScraper.Models.Train { #endregion - [JsonConverter(typeof(StatusKindConverter))] + [JsonConverter(typeof(StringEnumConverter), typeof(CamelCaseNamingStrategy))] public enum StatusKind { Passing, Arrival, Departure, } - [JsonConverter(typeof(NoteKindConverter))] + [JsonConverter(typeof(StringEnumConverter), typeof(CamelCaseNamingStrategy))] public enum NoteKind { TrainNumberChange, DetachingWagons, @@ -243,76 +243,4 @@ namespace InfoferScraper.Models.Train { } #endregion - - #region JSON Converters - - namespace JsonConverters { - internal class StatusKindConverter : JsonConverterFactory { - public override bool CanConvert(Type typeToConvert) { - return typeToConvert == typeof(StatusKind); - } - - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) { - return new Converter(); - } - - private class Converter : JsonConverter { - public override StatusKind Read( - ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options - ) { - return reader.GetString() switch { - "arrival" => StatusKind.Arrival, - "departure" => StatusKind.Departure, - "passing" => StatusKind.Passing, - _ => throw new NotImplementedException() - }; - } - - public override void Write(Utf8JsonWriter writer, StatusKind value, JsonSerializerOptions options) { - writer.WriteStringValue(value switch { - StatusKind.Passing => "passing", - StatusKind.Arrival => "arrival", - StatusKind.Departure => "departure", - _ => throw new NotImplementedException() - }); - } - } - } - - internal class NoteKindConverter : JsonConverterFactory { - public override bool CanConvert(Type typeToConvert) { - return typeToConvert == typeof(NoteKind); - } - - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) { - return new Converter(); - } - - private class Converter : JsonConverter { - public override NoteKind Read( - ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options - ) { - return reader.GetString() switch { - "departsAs" => NoteKind.DepartsAs, - "trainNumberChange" => NoteKind.TrainNumberChange, - "receivingWagons" => NoteKind.ReceivingWagons, - "detachingWagons" => NoteKind.DetachingWagons, - _ => throw new NotImplementedException() - }; - } - - public override void Write(Utf8JsonWriter writer, NoteKind value, JsonSerializerOptions options) { - writer.WriteStringValue(value switch { - NoteKind.DepartsAs => "departsAs", - NoteKind.TrainNumberChange => "trainNumberChange", - NoteKind.DetachingWagons => "detachingWagons", - NoteKind.ReceivingWagons => "receivingWagons", - _ => throw new NotImplementedException() - }); - } - } - } - } - - #endregion } diff --git a/server/Models/Database/StationAlias.cs b/server/Models/Database/StationAlias.cs index 71593a4..7293fc7 100644 --- a/server/Models/Database/StationAlias.cs +++ b/server/Models/Database/StationAlias.cs @@ -1,13 +1,13 @@ -using System.Text.Json.Serialization; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; +using Newtonsoft.Json; namespace Server.Models.Database; public record StationAlias( [property: BsonId] [property: BsonRepresentation(BsonType.ObjectId)] - [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] string? Id, string Name, [property: BsonRepresentation(BsonType.ObjectId)] diff --git a/server/Models/Database/StationListing.cs b/server/Models/Database/StationListing.cs index d5e678e..dc18c2a 100644 --- a/server/Models/Database/StationListing.cs +++ b/server/Models/Database/StationListing.cs @@ -1,14 +1,14 @@ using System.Collections.Generic; -using System.Text.Json.Serialization; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; +using Newtonsoft.Json; namespace Server.Models.Database; public record StationListing( [property: BsonId] [property: BsonRepresentation(BsonType.ObjectId)] - [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] string? Id, string Name, List StoppedAtBy diff --git a/server/Models/Database/TrainListing.cs b/server/Models/Database/TrainListing.cs index 0277b53..df26fda 100644 --- a/server/Models/Database/TrainListing.cs +++ b/server/Models/Database/TrainListing.cs @@ -1,14 +1,13 @@ -using System.Collections.Generic; -using System.Text.Json.Serialization; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; +using Newtonsoft.Json; namespace Server.Models.Database; public record TrainListing( [property: BsonId] [property: BsonRepresentation(BsonType.ObjectId)] - [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] string? Id, string Rank, string Number, diff --git a/server/Services/Implementations/Database.cs b/server/Services/Implementations/Database.cs index f3cbeda..dc068a2 100644 --- a/server/Services/Implementations/Database.cs +++ b/server/Services/Implementations/Database.cs @@ -2,9 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using InfoferScraper.Models.Station; @@ -13,6 +10,9 @@ using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; using scraper.Models.Itinerary; using Server.Models.Database; using Server.Utils; @@ -20,8 +20,10 @@ using Server.Utils; namespace Server.Services.Implementations; public class Database : Server.Services.Interfaces.IDatabase { - private static readonly JsonSerializerOptions serializerOptions = new() { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + private static readonly JsonSerializerSettings jsonSerializerSettings = new() { + ContractResolver = new DefaultContractResolver { + NamingStrategy = new CamelCaseNamingStrategy(), + }, }; private ILogger Logger { get; } @@ -79,54 +81,54 @@ public class Database : Server.Services.Interfaces.IDatabase { Logger.LogInformation("Migrating DB version 1 -> 2"); if (File.Exists(StationsFile)) { Logger.LogDebug("Converting StationsFile"); - var oldStations = JsonNode.Parse(File.ReadAllText(StationsFile)); + var oldStations = JToken.Parse(File.ReadAllText(StationsFile)); List stations = new(); if (oldStations != null) { - Logger.LogDebug("Found {StationsCount} stations", oldStations.AsArray().Count); - foreach (var station in oldStations.AsArray()) { + Logger.LogDebug("Found {StationsCount} stations", oldStations.Children().Count()); + foreach (var station in oldStations.Children()) { if (station == null) continue; - station["stoppedAtBy"] = new JsonArray(station["stoppedAtBy"]!.AsArray().Select(num => (JsonNode)(num!).ToString()!).ToArray()); + station["stoppedAtBy"] = new JArray(station["stoppedAtBy"]!.Children().Select(num => (JToken)(num!).ToString()!).ToArray()); } - stations = oldStations.Deserialize>(serializerOptions)!; + stations = oldStations.ToObject>(JsonSerializer.Create(jsonSerializerSettings))!; } Logger.LogDebug("Rewriting StationsFile"); - File.WriteAllText(StationsFile, JsonSerializer.Serialize(stations, serializerOptions)); + File.WriteAllText(StationsFile, JsonConvert.SerializeObject(stations, jsonSerializerSettings)); } if (File.Exists(TrainsFile)) { Logger.LogDebug("Converting TrainsFile"); - var oldTrains = JsonNode.Parse(File.ReadAllText(TrainsFile)); + var oldTrains = JToken.Parse(File.ReadAllText(TrainsFile)); List trains = new(); if (oldTrains != null) { - Logger.LogDebug("Found {TrainsCount} trains", oldTrains.AsArray().Count); - foreach (var train in oldTrains.AsArray()) { + Logger.LogDebug("Found {TrainsCount} trains", oldTrains.Children().Count()); + foreach (var train in oldTrains.Children()) { if (train == null) continue; train["number"] = train["numberString"]; - train.AsObject().Remove("numberString"); + train["numberString"]?.Remove(); } - trains = oldTrains.Deserialize>(serializerOptions)!; + trains = oldTrains.ToObject>(JsonSerializer.Create(jsonSerializerSettings))!; } Logger.LogDebug("Rewriting TrainsFile"); - File.WriteAllText(TrainsFile, JsonSerializer.Serialize(trains, serializerOptions)); + File.WriteAllText(TrainsFile, JsonConvert.SerializeObject(trains, jsonSerializerSettings)); } DbData = new(2); - File.WriteAllText(DbFile, JsonSerializer.Serialize(DbData, serializerOptions)); + File.WriteAllText(DbFile, JsonConvert.SerializeObject(DbData, jsonSerializerSettings)); Migration(); } else if (File.Exists(DbFile)) { - var oldDbData = JsonNode.Parse(File.ReadAllText(DbFile)); + var oldDbData = JToken.Parse(File.ReadAllText(DbFile)); if (((int?)oldDbData?["version"]) == 2) { Logger.LogInformation("Migrating DB version 2 -> 3 (transition from fs+JSON to MongoDB)"); if (File.Exists(StationsFile)) { Logger.LogDebug("Converting StationsFile"); - var stations = JsonSerializer.Deserialize>(File.ReadAllText(StationsFile)); + var stations = JsonConvert.DeserializeObject>(File.ReadAllText(StationsFile)); stationListingsCollection.InsertMany(stations); File.Delete(StationsFile); } if (File.Exists(TrainsFile)) { Logger.LogDebug("Converting TrainsFile"); - var trains = JsonSerializer.Deserialize>(File.ReadAllText(TrainsFile)); + var trains = JsonConvert.DeserializeObject>(File.ReadAllText(TrainsFile)); trainListingsCollection.InsertMany(trains); File.Delete(TrainsFile); } @@ -380,7 +382,7 @@ public class Database : Server.Services.Interfaces.IDatabase { public record DbRecord( [property: BsonId] [property: BsonRepresentation(BsonType.ObjectId)] - [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] string? Id, int Version ) { diff --git a/server/Startup.cs b/server/Startup.cs index 08ce2c3..ffaea98 100644 --- a/server/Startup.cs +++ b/server/Startup.cs @@ -1,6 +1,5 @@ using System; using System.Net; -using System.Text.Json; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -10,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using MongoDB.Bson.Serialization.Conventions; +using Newtonsoft.Json.Serialization; using Server.Models.Database; using Server.Services.Implementations; using Server.Services.Interfaces; @@ -37,8 +37,10 @@ namespace Server { services.AddSingleton(); services.AddSingleton(NodaTime.DateTimeZoneProviders.Tzdb); services.AddControllers() - .AddJsonOptions(options => { - options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + .AddNewtonsoftJson(options => { + options.SerializerSettings.ContractResolver = new DefaultContractResolver { + NamingStrategy = new CamelCaseNamingStrategy(), + }; }); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "InfoTren Scraper", Version = "v1" }); diff --git a/server/server.csproj b/server/server.csproj index 9d418a5..c06495a 100644 --- a/server/server.csproj +++ b/server/server.csproj @@ -9,6 +9,7 @@ +