在 ASP.NET Core 中使用 API 响应包装器

问题描述 投票:0回答:1

我仍然是一名业余程序员,试图调整我的技能,我读到的一个习惯是添加一致的 API 响应,以确保用户从我的 API 获得一致的结果。所以我创建了以下模型:

public class ResponseDTO<T>
{
    public required bool Succeeded { get; set; }
    public required string Message { get; set; } = "";
    public required int StatusCode {get; set;}
    public string[]? Errors { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public Pagination? Pagination {get; set;}
    public T Data { get; set; }
}

不清楚从最佳实践来看,如果数据被假定为 T 的单个结果而不是列表,我是否应该忽略分页?通过使用 JsonIgnore 属性,或者我应该始终返回分页数据。

我的第二个问题是如何捕获某些请求期间的错误。例如,对于文档上传请求,我有以下控制器:

    public async Task<IActionResult> AddRevisedCertificationAsync([FromForm] AddDocumentDTO addDocumentDTO)
    {
        try
        {
            var documentDTO = await _documentsService.AddRevisedCertificationAsync(addDocumentDTO);
            return Ok(new ResponseDTO<DocumentDTO>(){
                Succeeded = true,
                StatusCode = 200,
                Message = "The file have been successfully uploaded.",
                Data = documentDTO,
                Pagination = null});
        }
        catch(Exception ex)
        {
            var documentDTO = await _documentsService.AddRevisedCertificationAsync(addDocumentDTO);
            return Ok(new ResponseDTO<DocumentDTO>(){
                Succeeded = false,
                StatusCode = 400,
                Message = "The files were not uploaded due to a system error.",
                Data = null,
                Pagination = null});
        } 
    }

我是否应该在每个控制器中执行 try 和 catch 语句来捕获错误并将结果作为状态代码返回,尽管请求中的总体状态代码将显示 200,因为我使用 Ok() 返回?只是感觉很奇怪。另外,假设我知道有两种可能的例外情况。其中一个文档没有上传到我们的云存储,这是由于某些未知错误而导致的,或者该文件应该是 pdf 格式。我应该在 catch 语句中创建 if 语句来查找抛出的异常类型吗?就像在我的服务层中将 400 异常抛出回我的控制器一样,catch 中的 if 语句将指示上传失败,因为它需要 pdf,并在服务层中抛出 500 异常,如果文档因系统错误而未上传到框,并且再次在 if 语句中捕获它吗?

我只是在努力思考这一切应该如何运作,以便我可以通过我的应用程序一致地实现它。

asp.net-core exception asp.net-core-webapi
1个回答
0
投票

尚不清楚根据最佳实践,数据是否应该是 T 的单个结果而不是列表我应该忽略分页吗?经过 使用 JsonIgnore 属性还是应该始终返回分页 数据。

回答你这个问题:

如果

Data
属性包含单个对象而不是列表,则最好排除分页,在这种情况下使用
JsonIgnore
属性是合适的。

我的第二个问题是如何捕获某些请求期间的错误。为了 例如,对于文档上传请求,我有以下内容 控制器:

要处理代码中的错误,您可以使用 try-catch 时钟。

[HttpPost]
public async Task<IActionResult> AddRevisedCertificationAsync([FromForm] AddDocumentDTO addDocumentDTO)
{
    try
    {
        var documentDTO = await _documentsService.AddRevisedCertificationAsync(addDocumentDTO);
        return Ok(new ResponseDTO<DocumentDTO>()
        {
            Succeeded = true,
            StatusCode = 200,
            Message = "The file has been successfully uploaded.",
            Data = documentDTO
        });
    }
    catch (KnownException ex) // Replace 'KnownException' with your specific exceptions, e.g., FormatException for a PDF error.
    {
        return BadRequest(new ResponseDTO<DocumentDTO>()
        {
            Succeeded = false,
            StatusCode = 400,
            Message = ex.Message,
            Errors = new[] { "The file must be a PDF." }
        });
    }
    catch (Exception ex) // General exception handling for unknown errors.
    {
        return StatusCode(500, new ResponseDTO<DocumentDTO>()
        {
            Succeeded = false,
            StatusCode = 500,
            Message = "An unexpected error occurred.",
            Errors = new[] { ex.Message }
        });
    }
}

在服务层针对已知错误场景抛出特定异常,并在控制器中处理这些异常以提供一致的 API 响应:

public class InvalidFileFormatException : Exception
{
    public InvalidFileFormatException(string message) : base(message) { }
}

public class StorageException : Exception
{
    public StorageException(string message) : base(message) { }
}

服务层方法示例:

public async Task<DocumentDTO> AddRevisedCertificationAsync(AddDocumentDTO addDocumentDTO)
{
    if (addDocumentDTO.File == null || !IsPdf(addDocumentDTO.File))
    {
        throw new InvalidFileFormatException("The file must be a PDF.");
    }

    try
    {
        // Upload logic here
    }
    catch (Exception ex)
    {
        throw new StorageException("Failed to upload the document to Box.");
    }

    // Assume the upload was successful and return the DocumentDTO
}

您可以参考此文档了解更多详细信息:

处理 ASP.NET Core Web API 中的错误

© www.soinside.com 2019 - 2024. All rights reserved.