如何在没有204响应的情况下返回null?

问题描述

当我找不到任何数据时,控制器返回204。

[Route("api/[controller]")]
[ApiController]
public class SeasonsController : Controller
{
    private readonly IMediator _mediator;
    private readonly IMapper _mapper;

    public SeasonsController(IMediator mediator,IMapper mapper)
    {
        _mediator = mediator;
        _mapper = mapper;
    }

    [HttpGet,Route("by-betContextId/{betContextId:int}")]
    [SwaggerResponse(HttpStatusCode.OK,typeof(SeasonEntity))]
    public async Task<IActionResult> TryGetByBetContextId(int betContextId)
    {
        SeasonEntity entity = await _mediator.Send(new TryGetSeasonByBetContextId(betContextId));
        //the entity above can be null
        return Ok(entity);
    }
}

这是由nswag自动生成的客户端

 /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
    /// <exception cref="SportradarFaultException">A server side error occurred.</exception>
    public async System.Threading.Tasks.Task<SeasonEntity> TryGetByBetContextIdAsync(int betContextId,System.Threading.CancellationToken cancellationToken)
    {
        if (betContextId == null)
            throw new System.ArgumentNullException("betContextId");

        var urlBuilder_ = new System.Text.StringBuilder();
        urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Seasons/by-betContextId/{betContextId}");
        urlBuilder_.Replace("{betContextId}",System.Uri.EscapeDataString(ConvertToString(betContextId,System.Globalization.CultureInfo.InvariantCulture)));

        var client_ = _httpClient;
        try
        {
            using (var request_ = await CreateHttpRequestMessageAsync(cancellationToken).ConfigureAwait(false))
            {
                request_.Method = new System.Net.Http.HttpMethod("GET");
                request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));

                PrepareRequest(client_,request_,urlBuilder_);
                var url_ = urlBuilder_.ToString();
                request_.RequestUri = new System.Uri(url_,System.UriKind.RelativeOrAbsolute);
                PrepareRequest(client_,url_);

                var response_ = await client_.SendAsync(request_,System.Net.Http.HttpCompletionOption.ResponseHeadersRead,cancellationToken).ConfigureAwait(false);
                try
                {
                    var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers,h_ => h_.Key,h_ => h_.Value);
                    if (response_.Content != null && response_.Content.Headers != null)
                    {
                        foreach (var item_ in response_.Content.Headers)
                            headers_[item_.Key] = item_.Value;
                    }

                    ProcessResponse(client_,response_);

                    var status_ = (int)response_.StatusCode;
                    if (status_ == 200)
                    {
                        var objectResponse_ = await ReadObjectResponseAsync<SeasonEntity>(response_,headers_).ConfigureAwait(false);
                        if (objectResponse_.Object == null)
                        {
                            throw new SportradarFaultException("Response was null which was not expected.",status_,objectResponse_.Text,headers_,null);
                        }
                        return objectResponse_.Object;
                    }
                    else
                    {
                        var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); 
                        throw new SportradarFaultException("The HTTP status code of the response was not expected (" + status_ + ").",responseData_,null);
                    }
                }
                finally
                {
                    if (response_ != null)
                        response_.Dispose();
                }
            }
        }
        finally
        {
        }
    }

当我返回Ok()而不是Ok(entity)时,我会收到“响应为空,这是不期望的。”

当我从REST API客户端进行调用时,出现204错误。

当数据为空时,如何返回200?

解决方法

此问题与NSwag如何生成REST客户端API有关。

选项1:不要使用明显需要可解析的SeasonEntity的自动生成的NSwag客户端代码:

var objectResponse_ = await ReadObjectResponseAsync<SeasonEntity>(response_,headers_)
    .ConfigureAwait(false);
if (objectResponse_.Object == null)
{
    throw new SportradarFaultException("Response was null which was not expected.",status_,objectResponse_.Text,headers_,null);
}

选项2:确保在控制器操作中始终将SeasonEntity传递给Ok方法,以将检查传递给自动生成的客户端代码。

选项3:在404时返回entity == null响应:

[HttpGet,Route("by-betContextId/{betContextId:int}")]
[SwaggerResponse(HttpStatusCode.OK,typeof(SeasonEntity))]
public async Task<IActionResult> TryGetByBetContextId(int betContextId)
{
    SeasonEntity entity = await _mediator.Send(new TryGetSeasonByBetContextId(betContextId));

    if (entity == null)
        return NotFound();

    return Ok(entity);
}

选项3比选项2更有意义。为什么在找不到匹配项的情况下为什么要返回200响应?

,

我从更改了nswag.json配置

"defaultResponseReferenceTypeNullHandling": "NotNull",

"defaultResponseReferenceTypeNullHandling": "Null",

并将控制器更改为

[Route("api/[controller]")]
[ApiController]
public class SeasonsController : Controller
{
    private readonly IMediator _mediator;
    private readonly IMapper _mapper;

    public SeasonsController(IMediator mediator,IMapper mapper)
    {
        _mediator = mediator;
        _mapper = mapper;
    }

    [HttpGet,Route("TryGetByBetContextId")]
    [ProducesResponseType(typeof(SeasonEntity),StatusCodes.Status200OK)]
    public async Task<IActionResult> TryGetByBetContextId(int betContextId)
    {
        SeasonEntity entity = await _mediator.Send(new TryGetSeasonByBetContextId(betContextId));

        if (entity == null)
            return Ok();

        return Ok(entity);
    }
}
,

尝试用属性装饰控制器的方法

[return: CanBeNull]

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...