这个.NET 7最小API始终返回200。

huangapple go评论92阅读模式
英文:

This .NET 7 minimal API always returns 200

问题

I'm quite new to the concept of a minimal API, but the documentation seems quite clear. You only have to use Results or TypedResults to return the response code you want.

So I made a very basic try:

app.MapPost("/api/test", async context =>
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files["File"];
    Results.NoContent();
});

But even with that, it always returns a 200 status code. I also checked a lot of other material from .NET 6 and 7 (I target .NET 7) with method delegates that have a return type of Task<IResult> as specified here in the documentation, but I got the same result (200). Note that I also tried returning NotFound, but I still got the same.

app.MapPost("/api/test", TestReturn);

static async Task<IResult> TestReturn(HttpContext context)
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files["File"];
    return TypedResults.NoContent();
}

Why can't I get anything else than a 200?

英文:

I'm quite new to the concept of a minimal API, but the documentation seems quite clear. You only have to use Results or TypedResults to return the response code you want.

So I made a very basic try:

app.MapPost(&quot;/api/test&quot;, async context =&gt;
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files[&quot;File&quot;];
    Results.NoContent();
});

But even with that, it always returns a 200 status code. I also checked a lot of other material from .NET 6 and 7 (I target .NET 7) with method delegates that have a return type of Task&lt;IResult> as specified here in the documentation, but I got the same result (200). Note that I also tried returning NotFound, but I still got the same.

app.MapPost(&quot;/api/test&quot;, TestReturn);

static async Task&lt;IResult&gt; TestReturn(HttpContext context)
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files[&quot;File&quot;];
    return TypedResults.NoContent();
}

Why can't I get anything else than a 200?

答案1

得分: 2

这里有两个问题:

  1. 你忘记使用 return

    app.MapPost("/api/test", async context =>
    {
        var form = await context.Request.ReadFormAsync();
        var file = form.Files["File"];
        return Results.NoContent();
    });
    
  2. 有一个已知问题,异步处理程序只接受 HttpContext,你可以通过添加额外的参数(例如 CancellationToken)来解决:

    app.MapPost("/api/test", async (HttpContext context, CancellationToken ct) =>
    {
        var form = await context.Request.ReadFormAsync();
        var file = form.Files["File"];
        return Results.NoContent();
    });
    

此外,请注意,在 ASP.NET Core 7 中,绑定表单文件是内置支持的:

app.MapPost("/api/test", async (IFormFileCollection files) =>
{
    var file = files["File"];
    return Results.NoContent();
});

参考链接:

英文:

There are two issues here:

  1. You forgot to use return:

    app.MapPost(&quot;/api/test&quot;, async context =&gt;
    {
        var form = await context.Request.ReadFormAsync();
        var file = form.Files[&quot;File&quot;];
        return Results.NoContent();
    });
    
  2. There is a known issue with async handlers accepting HttpContext only, you can workaround by adding extra parameter (for example CancellationToken):

    app.MapPost(&quot;/api/test&quot;, async (HttpContext context, CancellationToken ct) =&gt;
    {
        var form = await context.Request.ReadFormAsync();
        var file = form.Files[&quot;File&quot;];
        return Results.NoContent();
    });
    

Also note that in ASP.NET Core 7 binding form files is supported out of the box:

app.MapPost(&quot;/api/test&quot;, async (IFormFileCollection files) =&gt;
{
    var file = files[&quot;File&quot;];
    return Results.NoContent();
});

See also:

答案2

得分: 0

你需要使用 return 实际返回结果。如果不这样做,默认情况下将返回 200 Ok

以下的 Program.cs 将在 .NET 7 上正常工作,并返回 204 No Content。我已经在 Postman 中测试过了。确保正确获取 URL、端口以及 HTTP 方法(例如 GET http://localhost:5097/test)。

FYI:该项目是使用 dotnet new webapi -o WebApiDemo 创建的,然后只更改了如下所示的 Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.MapGet("/test", () =>
{
    return TypedResults.NoContent();
});
app.MapControllers();
app.Run();
英文:

You need to actually return the result using return. If you don't by default 200 Ok will be returned.

The following Program.cs will work and return 204 No Content on .NET 7. I've tested it using Postman. Make sure to get the URL, port as well as HTTP method right (e.g. GET http://localhost:5097/test).

FYI: the project was created using dotnet new webapi -o WebApiDemo and then just the Program.cs was changed to what is shown below:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.MapGet(&quot;/test&quot;, () =&gt;
{
    return TypedResults.NoContent();
});
app.MapControllers();
app.Run();

答案3

得分: -3

在你的代码中,问题出在对 Results.NoContent()TypedResults.NoContent() 的使用上。这些方法实际上并不返回所需的HTTP状态码;相反,它们创建了一个表示“无内容”响应的结果对象,但它们需要从端点中返回才能产生任何效果。在你的代码中,你调用了这些方法,但没有从端点中返回它们的结果。

为了修复这个问题,并从你的极简API端点返回适当的状态码,你需要从端点本身返回结果。以下是如何修改你的代码以实现这一点的方式:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/api/test", async context =>
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files["File"];
    // 从端点返回 NoContentResult
    await context.Results.NoContent();
});

app.Run();

通过调用 await context.Results.NoContent();,你将从端点返回一个 NoContentResult,当访问端点时,它将产生一个204 No Content响应。

或者,如果你喜欢使用方法委托,你可以这样做:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/api/test", TestReturn);

static async Task TestReturn(HttpContext context)
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files["File"];
    // 从方法委托中返回 NoContentResult
    await context.Results.NoContent();
}

app.Run();

在这两种情况下,从端点或方法委托返回的 NoContentResult 将在访问端点时正确生成204 No Content响应。

英文:

In your code, the issue is with the usage of Results.NoContent() and TypedResults.NoContent(). These methods don't actually return the desired HTTP status code; instead, they create a result object that represents a "No Content" response, but they need to be returned from the endpoint to have any effect. In your code, you are calling these methods but not returning their result from the endpoint.

To fix the issue and return the appropriate status code from your minimal API endpoint, you need to return the result from the endpoint itself. Here's how you can modify your code to achieve that:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost(&quot;/api/test&quot;, async context =&gt;
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files[&quot;File&quot;];
    // Returning a NoContentResult from the endpoint
    await context.Results.NoContent();
});

app.Run();

By calling await context.Results.NoContent();, you are returning a NoContentResult from the endpoint, which will result in a 204 No Content response when the endpoint is accessed.

Alternatively, if you prefer to use a method delegate, you can do it like this:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost(&quot;/api/test&quot;, TestReturn);

static async Task TestReturn(HttpContext context)
{
    var form = await context.Request.ReadFormAsync();
    var file = form.Files[&quot;File&quot;];
    // Returning a NoContentResult from the method delegate
    await context.Results.NoContent();
}

app.Run();

In both cases, the NoContentResult returned from the endpoint or the method delegate will correctly produce a 204 No Content response when the endpoint is called.

huangapple
  • 本文由 发表于 2023年8月4日 20:48:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定