chore(net8): upgrade AspNetCore/Vue2/AdvancedSearch to .NET 8#35
chore(net8): upgrade AspNetCore/Vue2/AdvancedSearch to .NET 8#35devin-ai-integration[bot] wants to merge 3 commits into
Conversation
- Bump TFM to net8.0
- Upgrade EF Core (Sqlite, SqlServer) to 8.0.26
- Upgrade Microsoft.Data.SqlClient to 5.2.3
- Upgrade Microsoft.IdentityModel.JsonWebTokens / System.IdentityModel.Tokens.Jwt to 7.7.1
- Replace VueCliMiddleware with Microsoft.AspNetCore.SpaProxy 8.0.26
- Add SpaProxyServerUrl / SpaProxyLaunchCommand MSBuild properties
- Remove Microsoft.AspNetCore.SpaServices.Extensions
- Remove Newtonsoft.Json (no C# usages)
- Remove System.Data.SqlClient, System.Net.Http,
System.Text.RegularExpressions, System.Drawing.Common
- Startup.cs: drop UseSpaStaticFiles / AddSpaStaticFiles / UseSpa /
UseVueCli; use MapFallbackToFile("index.html") for SPA fallback
Co-Authored-By: Toby Drinkall <toby.drinkall@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…ation Microsoft.AspNetCore.SpaProxy ships its proxy/launch behavior via a HostingStartup assembly. Without the ASPNETCORE_HOSTINGSTARTUPASSEMBLIES env var pointing at it, the proxy middleware is never loaded and the Vue dev server is not auto-launched in Development. Mirror the pattern used by the Angular and Vue3 sibling projects' launchSettings.json. Co-Authored-By: Toby Drinkall <toby.drinkall@cognition.ai>
Without AddSpaStaticFiles/UseSpaStaticFiles, app.UseStaticFiles() and
MapFallbackToFile both look in wwwroot. Update the PublishRunWebpack
target to:
- reference the actual Vue CLI output dir (dist, not build), and
- rewrite RelativePath so files land under wwwroot/ in the publish
output.
Mirrors the pattern from AspNetCore/Angular/AdvancedSearch's csproj
so production routes resolve to the prebuilt SPA assets and
index.html is correctly served as the SPA fallback.
Co-Authored-By: Toby Drinkall <toby.drinkall@cognition.ai>
| // app should be already running before starting a .NET client | ||
| // spa.UseProxyToSpaDevelopmentServer("http://localhost:8080"); // your Vue app port | ||
| } | ||
| endpoints.MapFallbackToFile("index.html"); |
There was a problem hiding this comment.
🔴 Missing Vue dev server proxy configuration breaks API calls in development mode
The migration from VueCliMiddleware to Microsoft.AspNetCore.SpaProxy is incomplete. With SpaProxy, the browser is redirected to the SPA dev server URL (http://localhost:8085), so API requests made by the Vue app using relative URLs (e.g., /api/easyquery at ClientApp/src/views/EasyQuery.vue:155 and api/SampleData/WeatherForecasts at ClientApp/src/views/FetchData.vue:50) resolve to the Vue dev server origin, not the ASP.NET Core backend. All official .NET 8 SPA templates include a dev server proxy configuration (e.g., vite.config.js or proxy.conf.js) to forward /api requests to the ASP.NET Core server. Without a vue.config.js containing a devServer.proxy entry pointing /api to https://localhost:5001, all API calls will fail with 404 during development.
Prompt for agents
The migration from VueCliMiddleware to Microsoft.AspNetCore.SpaProxy requires a corresponding client-side proxy configuration. The old VueCliMiddleware reverse-proxied SPA requests from the ASP.NET Core server to the Vue dev server (browser stayed at ASP.NET Core URL). The new SpaProxy redirects the browser to the Vue dev server URL (http://localhost:8085), so the Vue dev server needs to proxy API requests back to the ASP.NET Core backend.
To fix this, create a file at ClientApp/vue.config.js with a devServer.proxy configuration that forwards /api requests to the ASP.NET Core server:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://localhost:5001',
secure: false
}
}
}
}
This ensures that API calls to /api/easyquery (used by EasyQuery.vue) and api/SampleData/WeatherForecasts (used by FetchData.vue) are correctly forwarded to the ASP.NET Core backend during development.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Acknowledged — this is a real concern but it is intentionally out of scope for this PR.
The parent task spec states:
Do NOT change anything in the Vue 2
ClientApp/JavaScript/TypeScript source unless strictly necessary to make the .NET build succeed.
A ClientApp/vue.config.js is a Vue/ClientApp source file, and it is not needed for the .NET build to succeed — dotnet build -c Release passes with 0 warnings, 0 errors. It would only be needed for runtime dev-server behavior (forwarding /api/* from the Vue dev server back to ASP.NET Core when SpaProxy redirects the browser to http://localhost:8085).
Since this is a ClientApp/ change with no impact on the .NET build, addressing it here would violate the parent task constraint. Flagging it as a known follow-up to be tracked in a separate PR (along with any other dev-mode SPA wiring decisions for this project) — see PR description.
For production, the just-pushed fix to PublishRunWebpack ensures the prebuilt dist/ is served directly from wwwroot by app.UseStaticFiles() + MapFallbackToFile("index.html"), so the runtime API + SPA work end-to-end without needing a dev-server proxy.
Summary
Upgrades
AspNetCore/Vue2/AdvancedSearch/EqDemo.AspNetCoreVue2.AdvancedSearch.csprojfrom .NET 6 to .NET 8 per the parent task spec, and replaces the deprecatedVueCliMiddleware/Microsoft.AspNetCore.SpaServices.Extensionsplumbing withMicrosoft.AspNetCore.SpaProxy..csprojchanges —AspNetCore/Vue2/AdvancedSearch/EqDemo.AspNetCoreVue2.AdvancedSearch.csproj<TargetFramework>net6.0net8.0Microsoft.EntityFrameworkCore.Sqlite6.0.18.0.26Microsoft.EntityFrameworkCore.SqlServer6.0.18.0.26Microsoft.Data.SqlClient2.1.75.2.3Microsoft.IdentityModel.JsonWebTokens6.34.07.7.1System.IdentityModel.Tokens.Jwt6.34.07.7.1VueCliMiddleware(deprecated)6.0.0Microsoft.AspNetCore.SpaServices.Extensions6.0.1Microsoft.AspNetCore.SpaProxy8.0.26(added)Newtonsoft.Json13.0.3System.Data.SqlClient4.8.6System.Net.Http4.3.4System.Text.RegularExpressions4.3.1System.Drawing.Common4.7.3<SpaRoot>ClientApp\ClientApp\(unchanged)<SpaProxyServerUrl>http://localhost:8085(added)<SpaProxyLaunchCommand>npm run serve -- --port 8085(added)PublishRunWebpack<DistFiles>$(SpaRoot)build\**$(SpaRoot)dist\**PublishRunWebpack<RelativePath>%(DistFiles.Identity)wwwroot\%(RecursiveDir)%(FileName)%(Extension)The
--port 8085flag preserves the previous dev-server port that was wired up viaspa.UseVueCli(npmScript: "serve", port: 8085, ...)without modifying anything underClientApp/.Code changes
AspNetCore/Vue2/AdvancedSearch/Startup.cs— required to compile after the package removals:using VueCliMiddleware;.services.AddSpaStaticFiles(...)(came fromMicrosoft.AspNetCore.SpaServices.Extensions, now gone).app.UseSpaStaticFiles()and the entireapp.UseSpa(spa => { ... spa.UseVueCli(...) ... })block.endpoints.MapFallbackToFile("index.html")to keep an SPA-style fallback for client-side routes.app.UseStaticFiles()is retained.AspNetCore/Vue2/AdvancedSearch/Properties/launchSettings.json— required forMicrosoft.AspNetCore.SpaProxyto activate:"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"to the environment variables of both theIIS ExpressandEqVueDemolaunch profiles.SpaProxyships its proxy/launch behavior via aHostingStartupassembly, so without this env var the middleware that auto-launches the Vue dev server would never load. Mirrors the pattern used byAspNetCore/Angular/AdvancedSearch/Properties/launchSettings.jsonandAspNetCore/Vue3/AdvancedSearch.Server/Properties/launchSettings.json. (Fix added in response to a Devin Review comment.)PublishRunWebpackMSBuild target — required so the production fallback (app.UseStaticFiles()+MapFallbackToFile("index.html")) finds the built SPA assets afterAddSpaStaticFiles/UseSpaStaticFileswere removed:<DistFiles>now references$(SpaRoot)dist\**(Vue CLI's actual output dir) instead of the broken$(SpaRoot)build\**(pre-existing bug).<RelativePath>now rewrites towwwroot\%(RecursiveDir)%(FileName)%(Extension)so the published SPA assets land underwwwroot/in the publish output, where the static-file middleware can serve them. MirrorsAspNetCore/Angular/AdvancedSearch/EqDemo.Angular.AdvancedSearch.csprojlines 64–70. (Fix added in response to a Devin Review comment.)Microsoft.AspNetCore.SpaProxyitself self-registers via theHostingStartupassembly attribute and is otherwise driven entirely by the<SpaProxyServerUrl>/<SpaProxyLaunchCommand>MSBuild properties — no explicitservices.Add...()call is required.Newtonsoft.Json: searched forNewtonsoft,JsonConvert,JObject,JArray,JTokenacross all.csfiles inAspNetCore/Vue2/AdvancedSearch/. There were zero usages, so removing the package required noSystem.Text.Jsonmigration.No changes to
Program.cs, controllers, models,Data/AppDbContext.cs, theSeed/folder, theClientApp/Vue source, or any files outside this project's scope.Build verification
Ran on the VM (with .NET SDK 8.0.420 installed via
dotnet-install.sh):Result: Build succeeded. 0 Warning(s). 0 Error(s).
CI status
Devin Review— passed (3 actionable findings posted on the PR have been addressed in follow-up commits:ASPNETCORE_HOSTINGSTARTUPASSEMBLIESinlaunchSettings.json, and thePublishRunWebpackdist/→wwwroot/mapping fix; one finding about a dev-server/apiproxy was acknowledged and intentionally deferred — see "Known follow-ups" below).security/snyk (Cognition-default)— failed (1 test failed). Details require authenticated access to https://app.snyk.io/org/cognition-default — flagging here for human review. All bumped/added packages (Microsoft.Data.SqlClient 5.2.3,Microsoft.EntityFrameworkCore.* 8.0.26,Microsoft.AspNetCore.SpaProxy 8.0.26,Microsoft.IdentityModel.JsonWebTokens 7.7.1,System.IdentityModel.Tokens.Jwt 7.7.1) are at the latest stable versions allowed by the parent task spec, so any flagged advisories are inherent to those latest stable releases (or to transitive deps now resolved differently undernet8.0).license/snyk (Cognition-default)— failed (1 test failed). Same caveat — likely a license-policy check on a transitive dependency that came along with the upgrade.Known follow-ups (intentionally out of scope)
/apiproxy inClientApp/: WithSpaProxy, the browser is redirected tohttp://localhost:8085in development, so relative/api/*calls inClientApp/src/views/*.vueresolve against the Vue dev server rather than the ASP.NET Core backend. Fixing this requires aClientApp/vue.config.jswith adevServer.proxyentry, which is outside the parent task's scope ("Do NOT change anything in the Vue 2ClientApp/JavaScript/TypeScript source unless strictly necessary to make the .NET build succeed"). Production routing is unaffected — the publishedwwwroot/content +app.UseStaticFiles()+MapFallbackToFile("index.html")serve the SPA and API from the same origin.Review & Testing Checklist for Human
.../licenseand decide whether the flagged advisory/license is acceptable. The package versions used are the latest stable allowed by the parent task spec, so resolution likely requires either a Snyk policy/ignore entry or a coordinated upgrade across the repo that's outside the scope of this single project.dotnet build AspNetCore/Vue2/AdvancedSearch/EqDemo.AspNetCoreVue2.AdvancedSearch.csproj -c Releaselocally on Windows / your build agent and confirm it succeeds with the .NET 8 SDK.dotnet publish AspNetCore/Vue2/AdvancedSearch/EqDemo.AspNetCoreVue2.AdvancedSearch.csproj -c Releaseand verify the published output containswwwroot/index.htmlplus the rest of the Vuedist/assets, and that browsing to a deep link (e.g./some/route) at runtime returnsindex.htmlvia the SPA fallback./apiproxy follow-up (see above) should be tracked in a separate PR or addressed alongside any other Vue 2 ClientApp modernization work.Notes
AspNetCore/Vue2/AdvancedSearch/. No other.csprojfiles, the solution files,global.json, orDirectory.Build.propswere touched — sibling projects are being upgraded by parallel sessions.Korzh.*andEasyData.*packages were left at their existing versions because the parent task explicitly limited package bumps to the listed set.Link to Devin session: https://app.devin.ai/sessions/7feb4eda30644a57bc3c581291322c46
Requested by: @tobydrinkall
Devin Review