Skip to content

Return ActionResult<T> instead of bare string from Navigation/generator endpoints #352

Description

@wrigjl

Context

Several controller actions return a bare string/String (or bool) instead of IActionResult/ActionResult<T>. These actions hand-serialize their payload with JsonSerializer.Serialize(...) and then return the resulting string.

Returning a bare string has two concrete consequences (both verified against a running instance):

  1. Wrong content type. A string return goes through ASP.NET Core's StringOutputFormatter, so the response is served as Content-Type: text/plain; charset=utf-8 — even though the body is JSON. Compare with ProblemProvider.*, which uses Content(..., "application/json") and correctly returns application/json.
  2. No error results. With a string return type the action cannot return BadRequest(...)/NotFound(...). Endpoints that take a problem name currently return an empty [] on unknown/invalid input instead of a proper 4xx.

Proposed change

Convert the affected actions to ActionResult<T> and return theObject; rather than JsonSerializer.Serialize(...), letting the framework serialize to application/json. Add BadRequest(...)/NotFound(...) on invalid input where a problem/reduction name is accepted.

Guideline going forward:

Use When
ActionResult<T> One well-defined success payload T, possibly plus error results. Swagger infers the 200 body; framework serializes as application/json.
IActionResult / non-generic ActionResult No single success type, or returning a raw ContentResult/FileResult.
bare string/bool/POCO Avoid.

Endpoints that need attention

Controller Route Method
ALL_ProblemsRefactorController GET Navigation/ALL_ProblemsRefactorController getDefault()
NPC_ProblemsRefactorController GET Navigation/NPC_ProblemsRefactorController getDefault()
P_ProblemsRefactorController GET Navigation/P_ProblemsRefactorController getDefault()
NPHard_ProblemsRefactorController GET Navigation/NPHard_ProblemsRefactorController getDefault()
NPC_NavGraph GET Navigation/NPC_NavGraph/availableReductions getConnectedProblems(chosenProblem) — takes a problem name; can't 400/404
NPC_NavGraph GET Navigation/NPC_NavGraph/reductionPath getPaths(reducingFrom, reducingTo) — takes problem names
Nav_Visualizations controller GET Navigation/{controller} getDefault(chosenProblem, problemType?)
Nav_Reductions controller GET Navigation/{controller} getDefault(source?, target?)
Nav_Verifiers controller GET Navigation/{controller} getDefault(chosenProblem, problemType?)
Nav_Solvers controller GET Navigation/{controller} getDefault(chosenProblem, problemType?)
ProblemGeneratorController GET ProblemGenerator/UndirectedGraph getUndirectedGraph(n, density, k)
ProblemGeneratorController GET ProblemGenerator/DirectedGraph getDirectedGraph(n, density, k)
ProblemGeneratorController GET ProblemGenerator/Sat3 getSat3(n, c)

Also worth fixing while here: the ProblemGeneratorController actions are annotated [ProducesResponseType(typeof(string[]), 200)] but return a single instance string, not an array.

Already correct (no change needed)

  • ProblemProvider.*IActionResult; mixes Content(..., "application/json") with BadRequest(...), no single T.
  • ContributerProfile.*IActionResult with Ok/NotFound.
  • ProblemTemplate.*ActionResult returning file downloads (no T).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions