diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-05-07 22:41:37 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-05-07 22:41:37 -0400 |
commit | a500812e88ac5a8acdd9732963e6fae95c0a73e6 (patch) | |
tree | 9f36571698b14ab4d898385d7bb14998efd30836 /src/SMAPI.Web | |
parent | c58d01d0cf45d6f5c7f75281cb6270afc68272db (diff) | |
download | SMAPI-a500812e88ac5a8acdd9732963e6fae95c0a73e6.tar.gz SMAPI-a500812e88ac5a8acdd9732963e6fae95c0a73e6.tar.bz2 SMAPI-a500812e88ac5a8acdd9732963e6fae95c0a73e6.zip |
update web project to .NET Core 3.1
Diffstat (limited to 'src/SMAPI.Web')
-rw-r--r-- | src/SMAPI.Web/BackgroundService.cs | 5 | ||||
-rw-r--r-- | src/SMAPI.Web/Framework/Extensions.cs | 15 | ||||
-rw-r--r-- | src/SMAPI.Web/Program.cs | 14 | ||||
-rw-r--r-- | src/SMAPI.Web/SMAPI.Web.csproj | 7 | ||||
-rw-r--r-- | src/SMAPI.Web/Startup.cs | 58 | ||||
-rw-r--r-- | src/SMAPI.Web/Views/JsonValidator/Index.cshtml | 2 | ||||
-rw-r--r-- | src/SMAPI.Web/Views/LogParser/Index.cshtml | 14 | ||||
-rw-r--r-- | src/SMAPI.Web/Views/Mods/Index.cshtml | 8 |
8 files changed, 75 insertions, 48 deletions
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 /// <summary>Construct an instance.</summary> /// <param name="wikiCache">The cache in which to store wiki metadata.</param> /// <param name="modCache">The cache in which to store mod data.</param> - public BackgroundService(IWikiCacheRepository wikiCache, IModCacheRepository modCache) + /// <param name="hangfireStorage">The Hangfire storage implementation.</param> + [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; } + + /// <summary>Get a serialized JSON representation of the value.</summary> + /// <param name="page">The page to extend.</param> + /// <param name="value">The value to serialize.</param> + /// <returns>The serialized JSON.</returns> + /// <remarks>This bypasses unnecessary validation (e.g. not allowing null values) in <see cref="IJsonHelper.Serialize"/>.</remarks> + 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 /// <param name="args">The command-line arguments.</param> 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<Startup>() + .ConfigureWebHostDefaults(builder => builder + .CaptureStartupErrors(true) + .UseSetting("detailedErrors", "true") + .UseStartup<Startup>() + ) .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 @@ <PropertyGroup> <AssemblyName>SMAPI.Web</AssemblyName> <RootNamespace>StardewModdingAPI.Web</RootNamespace> - <TargetFramework>netcoreapp2.0</TargetFramework> + <TargetFramework>netcoreapp3.1</TargetFramework> <LangVersion>latest</LangVersion> </PropertyGroup> @@ -20,10 +20,7 @@ <PackageReference Include="Humanizer.Core" Version="2.8.11" /> <PackageReference Include="JetBrains.Annotations" Version="2020.1.0" /> <PackageReference Include="Markdig" Version="0.20.0" /> - <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" /> + <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.2" /> <PackageReference Include="Mongo2Go" Version="2.2.12" /> <PackageReference Include="MongoDB.Driver" Version="2.10.4" /> <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" /> 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 *********/ /// <summary>Construct an instance.</summary> /// <param name="env">The hosting environment.</param> - public Startup(IHostingEnvironment env) + public Startup(IWebHostEnvironment env) { this.Configuration = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) @@ -71,25 +71,16 @@ namespace StardewModdingAPI.Web .Configure<SiteConfig>(this.Configuration.GetSection("Site")) .Configure<RouteOptions>(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<MongoDbConfig>(); - // init background service - { - BackgroundServicesConfig config = this.Configuration.GetSection("BackgroundServices").Get<BackgroundServicesConfig>(); - if (config.Enabled) - services.AddHostedService<BackgroundService>(); - } + // init MVC + services + .AddControllers() + .AddNewtonsoftJson(options => this.ConfigureJsonNet(options.SerializerSettings)) + .ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider())); + services + .AddRazorPages(); // init MongoDB services.AddSingleton<MongoDbRunner>(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<BackgroundServicesConfig>(); + if (config.Enabled) + services.AddHostedService<BackgroundService>(); + } + // init API clients { ApiClientsConfig api = this.Configuration.GetSection("ApiClients").Get<ApiClientsConfig>(); @@ -188,8 +186,7 @@ namespace StardewModdingAPI.Web /// <summary>The method called by the runtime to configure the HTTP request pipeline.</summary> /// <param name="app">The application builder.</param> - /// <param name="env">The hosting environment.</param> - 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 *********/ + /// <summary>Configure a Json.NET serializer.</summary> + /// <param name="settings">The serializer settings to edit.</param> + 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; + } + /// <summary>Get the redirect rules to apply.</summary> 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 @@ <script src="~/Content/js/json-validator.js?r=202002"></script> <script> $(function() { - smapi.jsonValidator(@Json.Serialize(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = "$schemaName", id = "$id" })), @Json.Serialize(Model.PasteID)); + smapi.jsonValidator(@this.ForJson(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = "$schemaName", id = "$id" })), @this.ForJson(Model.PasteID)); }); </script> } 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<LogLevel>() .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 @@ <script> $(function() { smapi.logParser({ - logStarted: new Date(@Json.Serialize(Model.ParsedLog?.Timestamp)), - showPopup: @Json.Serialize(Model.ParsedLog == null), - showMods: @Json.Serialize(Model.ParsedLog?.Mods?.Select(p => Model.GetSlug(p.Name)).Distinct().ToDictionary(slug => slug, slug => true), noFormatting), - showSections: @Json.Serialize(Enum.GetNames(typeof(LogSection)).ToDictionary(section => section, section => false), noFormatting), - showLevels: @Json.Serialize(defaultFilters, noFormatting), - enableFilters: @Json.Serialize(!Model.ShowRaw) + logStarted: new Date(@this.ForJson(Model.ParsedLog?.Timestamp)), + showPopup: @this.ForJson(Model.ParsedLog == null), + showMods: @this.ForJson(Model.ParsedLog?.Mods?.Select(p => Model.GetSlug(p.Name)).Distinct().ToDictionary(slug => slug, slug => true)), + showSections: @this.ForJson(Enum.GetNames(typeof(LogSection)).ToDictionary(section => section, section => false)), + showLevels: @this.ForJson(defaultFilters), + enableFilters: @this.ForJson(!Model.ShowRaw) }, '@this.Url.PlainAction("Index", "LogParser", values: null)'); }); </script> 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 @@ <script src="~/Content/js/mods.js?r=20200218"></script> <script> $(function() { - var data = @Json.Serialize(Model.Mods, new JsonSerializerSettings { Formatting = Formatting.None }); - var enableBeta = @Json.Serialize(Model.BetaVersion != null); + var data = @this.ForJson(Model.Mods); + var enableBeta = @this.ForJson(Model.BetaVersion != null); smapi.modList(data, enableBeta); }); </script> @@ -86,7 +86,7 @@ else </td> <td class="mod-page-links"> <span v-for="(link, i) in mod.ModPages"> - <a v-bind:href="link.Url">{{link.Text}}</a>{{i < mod.ModPages.length - 1 ? ', ' : ''}} + <a v-bind:href="link.Url">{{link.Text}}</a>{{i < mod.ModPages.length - 1 ? ', ' : ''}} </span> </td> <td> |