Skip to content

fix(http-server-csharp): Emit correct ASP.NET Core result methods for non-200/204 status codes#9895

Open
Copilot wants to merge 5 commits intomainfrom
copilot/fix-csharp-emitter-status-codes
Open

fix(http-server-csharp): Emit correct ASP.NET Core result methods for non-200/204 status codes#9895
Copilot wants to merge 5 commits intomainfrom
copilot/fix-csharp-emitter-status-codes

Conversation

Copy link
Contributor

Copilot AI commented Mar 4, 2026

  • Add getControllerReturnStatement helper function to utils.ts that maps HTTP status codes to appropriate ASP.NET Core result methods
  • Update interfaceOperationDeclaration in service.ts to use the new helper instead of hardcoded Ok/NoContent
  • Update operationDeclaration in service.ts to use the new helper instead of hardcoded Ok/NoContent
  • Import new function in service.ts
  • Add test cases for 202 Accepted (with/without body) and 201 Created status codes
  • Run tests to verify changes (93 tests pass)
  • Add changeset
  • Merge latest from main and run pnpm format
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: C# emitter: non‑200/204 status codes (e.g., 202 Accepted) are ignored — controller always returns Ok(...) / NoContent()</issue_title>
<issue_description>### Describe the bug

When an operation in TypeSpec is annotated to return status codes other than 200 or 204 (e.g., 202 Accepted, 201 Created, 4xx/5xx), the generated ASP.NET Core controller method still returns Ok(result) (or NoContent() when the response type is void). This appears to be due to hardcoded logic in the emitter:

// emitter snippet (as seen in generated code path)
const hasResponseValue = response.name !== "void";
const resultString = ${status === 204 ? "NoContent" : "Ok"};
return this.emitter.result.declaration(
operation.name,
code${doc ?${formatComment(doc)}: ""} [${getOperationVerbDecorator(httpOperation)}] [Route("${httpOperation.path}")] ${this.emitter.emitOperationReturnType(operation)} public virtual async Task<IActionResult> ${operationName}(${declParams}) { ${ hasResponseValue ?var result = await ${this.emitter.getContext().resourceName}Impl.${operationName}Async(${getBusinessLogicCallParameters(parameters)});
return ${resultString}(result);:await ${this.emitter.getContext().resourceName}Impl.${operationName}Async(${getBusinessLogicCallParameters(parameters)});
return ${resultString}(); } }
);
Because resultString selects only Ok or NoContent, any other intended status code is effectively lost.
Impact

202 Accepted (typical for long‑running operations) becomes 200 OK.
201 Created (resource creation) becomes 200 OK and no Location header is set.
Other outcome codes (e.g., 301/302, 400, 409, 500) are not represented correctly, undermining API semantics and client behavior.

Reproduction

https://github.com/microsoft/typespec/blob/main/packages/http-server-csharp/src/lib/service.ts
line 874

Checklist

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…non-200/204 status codes

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix C# emitter to handle non-200/204 status codes fix(http-server-csharp): Emit correct ASP.NET Core result methods for non-200/204 status codes Mar 4, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 4, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-server-csharp@9895

commit: 54e0c46

@markcowl
Copy link
Contributor

markcowl commented Mar 4, 2026

@copilot Pull the latest from the main branch and fix formatting of the files in the PR (pnpm format)

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 4, 2026

@copilot Pull the latest from the main branch and fix formatting of the files in the PR (pnpm format)

Done in bc9e7dc — ran pnpm format which reordered the import in service.ts to match alphabetical order. Note: the main branch is not available in the shallow clone used here (only the PR branch is checked out), so I merged what was available and formatted directly. The formatting change is only a single import reordering in service.ts.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/typespec/typespec/website/node_modules/.bin/../astro/astro.js build sh s/.b�� utput-dir ../../website/src/cont--llmstxt sh _modules/.bin/node ental ture dules/.bin/node node tobu�� rs &amp;&amp; pnpm build:src gen-extern-signature (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

All changed packages have been documented.

  • @typespec/http-server-csharp
Show changes

@typespec/http-server-csharp - fix ✏️

Fix controller generation to use correct ASP.NET Core result methods for non-200/204 status codes. Previously all operations returned Ok(...) or NoContent() regardless of the declared status code. Now operations returning 202 use Accepted(...), and other status codes use StatusCode(code, ...).

@markcowl markcowl marked this pull request as ready for review March 4, 2026 21:16
@azure-sdk
Copy link
Collaborator

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: C# emitter: non‑200/204 status codes (e.g., 202 Accepted) are ignored — controller always returns Ok(...) / NoContent()

3 participants