Net 6 Minimal API 中的自定义结果

在 ASP.NET Core 5 中,我有一个自定义操作结果,如下所示:

public class ErrorResult : ActionResult {

  private readonly IList<Error> _errors;

  public ErrorResult(IList<Error> errors) {
    _errors = errors;
  }

  public override async Task ExecuteResultAsync(ActionContext context) {

    // Code that creates Response

    await result.ExecuteResultAsync(context);

  }

}

然后在控制器动作上,我会:

return new ErrorResult(errors);

如何在 NET 6 Minimal API 中做类似的事情?

我一直在研究它,我认为我应该实现 IResult。

但我不确定这是否是解决方案或如何做到这一点。

stack overflow Custom Result in Net 6 Minimal API
原文答案

答案:

作者头像

如果你仍然想使用 MVC (Model-View-Controller),你仍然可以使用自定义 ActionResult。

如果您只想使用 Minimal API 进行响应,那么您必须实现 IResultTask<IResult>ValueTask<IResult>

app.MapGet("/hello", () => Results.Ok(new { Message = "Hello World" }));

以下示例使用内置结果类型来自定义响应:

app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
         await db.Todos.FindAsync(id) 
         is Todo todo
         ? Results.Ok(todo) 
         : Results.NotFound())
   .Produces<Todo>(StatusCodes.Status200OK)
   .Produces(StatusCodes.Status404NotFound);

您可以在此处找到更多 IResult 实现 sampleshttps://github.com/dotnet/aspnetcore/tree/main/src/Http/Http.Results/src

链接: Minimal APIs overview | Microsoft Docs

作者头像

我最近一直在使用最少的 API 并致力于全局异常处理。到目前为止,这是我想出的。

1.创建IResult的类实现

  • 创建一个构造函数,它将接受您想要进入 IResult 响应的详细信息的参数。 APIErrorDetails 是我的一个自定义实现,类似于您在 MVC 中的 ProblemDetails 中看到的。方法实现对您的任何要求都是开放的。

    
    public class ExceptionAllResult : IResult
    {
    private readonly ApiErrorDetails _details;
    
    public ExceptionAllResult(ApiErrorDetails details)
    {
        _details = details;
    }
    public async Task ExecuteAsync(HttpContext httpContext)
    {
        var jsonDetails = JsonSerializer.Serialize(_details);
        httpContext.Response.ContentType = MediaTypeNames.Application.Json;
        httpContext.Response.ContentLength = Encoding.UTF8.GetByteCount(jsonDetails);
        httpContext.Response.StatusCode = _details.StatusCode;
        await httpContext.Response.WriteAsync(jsonDetails);
    }
    }

2. 在 Program.cs 文件中的异常处理中间件中返回结果。

app.UseExceptionHandler(
x =>
{

            x.Run(
                async context =>
                {
                    // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-6.0
                    var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();

                    // Whatever you want for null handling
                    if (exceptionFeature is null) throw new Exception(); 

                    // My result service for creating my API details from the HTTP context and exception. This returns the Result class seen in the code snippet above
                    var result = resultService.GetErrorResponse(exceptionFeature.Error, context);
                    await result.ExecuteAsync(context); // returns the custom result
                });
        }
    );