Skip to content

Commit 506d8fd

Browse files
authored
[http-server-csharp]: Fix routing issues with MFD requests (microsoft#5505)
1 parent 2edfa93 commit 506d8fd

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
3+
changeKind: fix
4+
packages:
5+
- "@typespec/http-server-csharp"
6+
---
7+
8+
[http-server-csharp]: Fix routing issues with MFD requests

packages/http-server-csharp/src/service.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ export async function $onEmit(context: EmitContext<CSharpServiceEmitterOptions>)
661661
const multipart: boolean = this.#isMultipartRequest(httpOperation);
662662
const declParams = !multipart
663663
? this.#emitHttpOperationParameters(httpOperation)
664-
: this.#emitHttpOperationParameters(httpOperation, "HttpRequest request, Stream body");
664+
: this.#emitHttpOperationParameters(httpOperation, true);
665665

666666
if (multipart) {
667667
const context = this.emitter.getContext();
@@ -720,14 +720,14 @@ export async function $onEmit(context: EmitContext<CSharpServiceEmitterOptions>)
720720
${this.emitter.emitOperationReturnType(operation)}
721721
public virtual async Task<IActionResult> ${operationName}(${declParams})
722722
{
723-
var boundary = request.GetMultipartBoundary();
723+
var boundary = Request.GetMultipartBoundary();
724724
if (boundary == null)
725725
{
726726
return BadRequest("Request missing multipart boundary");
727727
}
728728
729729
730-
var reader = new MultipartReader(boundary, body);
730+
var reader = new MultipartReader(boundary, Request.Body);
731731
${
732732
hasResponseValue
733733
? `var result = await ${this.emitter.getContext().resourceName}Impl.${operationName}Async(${this.#emitOperationCallParameters(httpOperation, "reader")});
@@ -912,7 +912,7 @@ export async function $onEmit(context: EmitContext<CSharpServiceEmitterOptions>)
912912

913913
#emitHttpOperationParameters(
914914
operation: HttpOperation,
915-
bodyParameter?: string,
915+
bodyParameter?: boolean,
916916
): EmitterOutput<string> {
917917
const signature = new StringBuilder();
918918
const bodyParam = operation.parameters.body;
@@ -930,10 +930,16 @@ export async function $onEmit(context: EmitContext<CSharpServiceEmitterOptions>)
930930
for (const parameter of requiredParams) {
931931
signature.push(
932932
code`${this.#emitOperationSignatureParameter(operation, parameter)}${
933-
++i < requiredParams.length || bodyParam !== undefined ? ", " : ""
933+
++i < requiredParams.length ? ", " : ""
934934
}`,
935935
);
936936
}
937+
if (
938+
requiredParams.length > 0 &&
939+
(optionalParams.length > 0 || (bodyParameter === undefined && bodyParam !== undefined))
940+
) {
941+
signature.push(code`, `);
942+
}
937943
if (bodyParameter === undefined) {
938944
if (bodyParam !== undefined) {
939945
signature.push(
@@ -942,11 +948,9 @@ export async function $onEmit(context: EmitContext<CSharpServiceEmitterOptions>)
942948
bodyParam.type,
943949
Visibility.Create || Visibility.Update,
944950
),
945-
)} body${optionalParams.length > 0 ? ", " : ""}`,
951+
)} body${requiredParams.length > 0 && optionalParams.length > 0 ? ", " : ""}`,
946952
);
947953
}
948-
} else {
949-
signature.push(code`${bodyParameter}${optionalParams.length > 0 ? ", " : ""}`);
950954
}
951955
i = 0;
952956
for (const parameter of optionalParams) {

packages/http-server-csharp/test/generation.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,17 +1123,19 @@ it("handles multipartBody requests and shared routes", async () => {
11231123
}
11241124
11251125
@sharedRoute
1126-
@route("/foo")
1126+
@route("/foo/{id}")
11271127
@post
11281128
op fooBinary(
1129+
@path id: string,
11291130
@header("content-type") contentType: "multipart/form-data",
11301131
@multipartBody body: FooRequest
11311132
): void;
11321133
11331134
@sharedRoute
1134-
@route("/foo")
1135+
@route("/foo/{id}")
11351136
@post
11361137
op fooJson(
1138+
@path id: string,
11371139
@header("content-type") contentType: "application/json",
11381140
@body body: FooJsonRequest
11391141
): void;
@@ -1154,18 +1156,18 @@ it("handles multipartBody requests and shared routes", async () => {
11541156
"using Microsoft.AspNetCore.WebUtilities;",
11551157
"using Microsoft.AspNetCore.Http.Extensions;",
11561158
`[Consumes("multipart/form-data")]`,
1157-
"public virtual async Task<IActionResult> FooBinary(HttpRequest request, Stream body)",
1158-
".FooBinaryAsync(reader)",
1159-
"public virtual async Task<IActionResult> FooJson(FooJsonRequest body)",
1160-
".FooJsonAsync(body)",
1159+
"public virtual async Task<IActionResult> FooBinary(string id)",
1160+
".FooBinaryAsync(id, reader)",
1161+
"public virtual async Task<IActionResult> FooJson(string id, FooJsonRequest body)",
1162+
".FooJsonAsync(id, body)",
11611163
],
11621164
],
11631165
[
11641166
"IContosoOperations.cs",
11651167
[
11661168
"using Microsoft.AspNetCore.WebUtilities;",
1167-
"Task FooBinaryAsync( MultipartReader reader);",
1168-
"Task FooJsonAsync( FooJsonRequest body);",
1169+
"Task FooBinaryAsync( string id, MultipartReader reader);",
1170+
"Task FooJsonAsync( string id, FooJsonRequest body);",
11691171
],
11701172
],
11711173
[

0 commit comments

Comments
 (0)