问题描述
当我找不到任何数据时,控制器返回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]