From a500812e88ac5a8acdd9732963e6fae95c0a73e6 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 7 May 2020 22:41:37 -0400 Subject: update web project to .NET Core 3.1 --- src/SMAPI.Web/BackgroundService.cs | 5 ++- src/SMAPI.Web/Framework/Extensions.cs | 15 +++++++ src/SMAPI.Web/Program.cs | 14 +++---- src/SMAPI.Web/SMAPI.Web.csproj | 7 +--- src/SMAPI.Web/Startup.cs | 58 ++++++++++++++++---------- src/SMAPI.Web/Views/JsonValidator/Index.cshtml | 2 +- src/SMAPI.Web/Views/LogParser/Index.cshtml | 14 +++---- src/SMAPI.Web/Views/Mods/Index.cshtml | 8 ++-- 8 files changed, 75 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/SMAPI.Web/BackgroundService.cs b/src/SMAPI.Web/BackgroundService.cs index ee7a60f3..275622fe 100644 --- a/src/SMAPI.Web/BackgroundService.cs +++ b/src/SMAPI.Web/BackgroundService.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Hangfire; @@ -36,7 +37,9 @@ namespace StardewModdingAPI.Web /// Construct an instance. /// The cache in which to store wiki metadata. /// The cache in which to store mod data. - public BackgroundService(IWikiCacheRepository wikiCache, IModCacheRepository modCache) + /// The Hangfire storage implementation. + [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "The Hangfire reference forces it to initialize first, since it's needed by the background service.")] + public BackgroundService(IWikiCacheRepository wikiCache, IModCacheRepository modCache, JobStorage hangfireStorage) { BackgroundService.WikiCache = wikiCache; BackgroundService.ModCache = modCache; diff --git a/src/SMAPI.Web/Framework/Extensions.cs b/src/SMAPI.Web/Framework/Extensions.cs index e0da1424..96463233 100644 --- a/src/SMAPI.Web/Framework/Extensions.cs +++ b/src/SMAPI.Web/Framework/Extensions.cs @@ -1,8 +1,12 @@ using System; using JetBrains.Annotations; +using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Razor; +using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Routing; +using Newtonsoft.Json; namespace StardewModdingAPI.Web.Framework { @@ -34,5 +38,16 @@ namespace StardewModdingAPI.Web.Framework } return url; } + + /// Get a serialized JSON representation of the value. + /// The page to extend. + /// The value to serialize. + /// The serialized JSON. + /// This bypasses unnecessary validation (e.g. not allowing null values) in . + public static IHtmlContent ForJson(this RazorPageBase page, object value) + { + string json = JsonConvert.SerializeObject(value); + return new HtmlString(json); + } } } diff --git a/src/SMAPI.Web/Program.cs b/src/SMAPI.Web/Program.cs index 70082160..1fdd3185 100644 --- a/src/SMAPI.Web/Program.cs +++ b/src/SMAPI.Web/Program.cs @@ -1,5 +1,5 @@ -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; namespace StardewModdingAPI.Web { @@ -13,13 +13,13 @@ namespace StardewModdingAPI.Web /// The command-line arguments. public static void Main(string[] args) { - // configure web server - WebHost + Host .CreateDefaultBuilder(args) - .CaptureStartupErrors(true) - .UseSetting("detailedErrors", "true") - .UseKestrel().UseIISIntegration() // must be used together; fixes intermittent errors on Azure: https://stackoverflow.com/a/38312175/262123 - .UseStartup() + .ConfigureWebHostDefaults(builder => builder + .CaptureStartupErrors(true) + .UseSetting("detailedErrors", "true") + .UseStartup() + ) .Build() .Run(); } diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj index c3972758..7ed79ea3 100644 --- a/src/SMAPI.Web/SMAPI.Web.csproj +++ b/src/SMAPI.Web/SMAPI.Web.csproj @@ -3,7 +3,7 @@ SMAPI.Web StardewModdingAPI.Web - netcoreapp2.0 + netcoreapp3.1 latest @@ -20,10 +20,7 @@ - - - - + diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs index 56ef9a79..07869797 100644 --- a/src/SMAPI.Web/Startup.cs +++ b/src/SMAPI.Web/Startup.cs @@ -47,7 +47,7 @@ namespace StardewModdingAPI.Web *********/ /// Construct an instance. /// The hosting environment. - public Startup(IHostingEnvironment env) + public Startup(IWebHostEnvironment env) { this.Configuration = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) @@ -71,25 +71,16 @@ namespace StardewModdingAPI.Web .Configure(this.Configuration.GetSection("Site")) .Configure(options => options.ConstraintMap.Add("semanticVersion", typeof(VersionConstraint))) .AddLogging() - .AddMemoryCache() - .AddMvc() - .ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider())) - .AddJsonOptions(options => - { - foreach (JsonConverter converter in new JsonHelper().JsonSettings.Converters) - options.SerializerSettings.Converters.Add(converter); - - options.SerializerSettings.Formatting = Formatting.Indented; - options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; - }); + .AddMemoryCache(); MongoDbConfig mongoConfig = this.Configuration.GetSection("MongoDB").Get(); - // init background service - { - BackgroundServicesConfig config = this.Configuration.GetSection("BackgroundServices").Get(); - if (config.Enabled) - services.AddHostedService(); - } + // init MVC + services + .AddControllers() + .AddNewtonsoftJson(options => this.ConfigureJsonNet(options.SerializerSettings)) + .ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider())); + services + .AddRazorPages(); // init MongoDB services.AddSingleton(serv => !mongoConfig.IsConfigured() @@ -121,7 +112,7 @@ namespace StardewModdingAPI.Web if (mongoConfig.IsConfigured()) { - config.UseMongoStorage(mongoConfig.ConnectionString, $"{mongoConfig.Database}-hangfire", new MongoStorageOptions + config.UseMongoStorage(MongoClientSettings.FromConnectionString(mongoConfig.ConnectionString), $"{mongoConfig.Database}-hangfire", new MongoStorageOptions { MigrationOptions = new MongoMigrationOptions(MongoMigrationStrategy.Drop), CheckConnection = false // error on startup takes down entire process @@ -131,6 +122,13 @@ namespace StardewModdingAPI.Web config.UseMemoryStorage(); }); + // init background service + { + BackgroundServicesConfig config = this.Configuration.GetSection("BackgroundServices").Get(); + if (config.Enabled) + services.AddHostedService(); + } + // init API clients { ApiClientsConfig api = this.Configuration.GetSection("ApiClients").Get(); @@ -188,8 +186,7 @@ namespace StardewModdingAPI.Web /// The method called by the runtime to configure the HTTP request pipeline. /// The application builder. - /// The hosting environment. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) + public void Configure(IApplicationBuilder app) { // basic config app.UseDeveloperExceptionPage(); @@ -201,7 +198,13 @@ namespace StardewModdingAPI.Web ) .UseRewriter(this.GetRedirectRules()) .UseStaticFiles() // wwwroot folder - .UseMvc(); + .UseRouting() + .UseAuthorization() + .UseEndpoints(p => + { + p.MapControllers(); + p.MapRazorPages(); + }); // enable Hangfire dashboard app.UseHangfireDashboard("/tasks", new DashboardOptions @@ -215,6 +218,17 @@ namespace StardewModdingAPI.Web /********* ** Private methods *********/ + /// Configure a Json.NET serializer. + /// The serializer settings to edit. + private void ConfigureJsonNet(JsonSerializerSettings settings) + { + foreach (JsonConverter converter in new JsonHelper().JsonSettings.Converters) + settings.Converters.Add(converter); + + settings.Formatting = Formatting.Indented; + settings.NullValueHandling = NullValueHandling.Ignore; + } + /// Get the redirect rules to apply. private RewriteOptions GetRedirectRules() { diff --git a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml index 7287e00b..f255a72f 100644 --- a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml +++ b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml @@ -40,7 +40,7 @@ } diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 2183992b..9b611bcd 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -1,5 +1,4 @@ @using Humanizer -@using Newtonsoft.Json @using StardewModdingAPI.Toolkit.Utilities @using StardewModdingAPI.Web.Framework @using StardewModdingAPI.Web.Framework.LogParsing.Models @@ -12,7 +11,6 @@ .GetValues(typeof(LogLevel)) .Cast() .ToDictionary(level => level.ToString().ToLower(), level => level != LogLevel.Trace); - JsonSerializerSettings noFormatting = new JsonSerializerSettings { Formatting = Formatting.None }; string curPageUrl = this.Url.PlainAction("Index", "LogParser", new { id = Model.PasteID }, absoluteUrl: true); } @@ -32,12 +30,12 @@ diff --git a/src/SMAPI.Web/Views/Mods/Index.cshtml b/src/SMAPI.Web/Views/Mods/Index.cshtml index b1d9ae2c..f5506287 100644 --- a/src/SMAPI.Web/Views/Mods/Index.cshtml +++ b/src/SMAPI.Web/Views/Mods/Index.cshtml @@ -1,6 +1,6 @@ @using Humanizer @using Humanizer.Localisation -@using Newtonsoft.Json +@using StardewModdingAPI.Web.Framework @model StardewModdingAPI.Web.ViewModels.ModListModel @{ ViewData["Title"] = "Mod compatibility"; @@ -15,8 +15,8 @@ @@ -86,7 +86,7 @@ else - {{link.Text}}{{i < mod.ModPages.length - 1 ? ', ' : ''}} + {{link.Text}}{{i < mod.ModPages.length - 1 ? ', ' : ''}} -- cgit