我有一个ASP.NET Core API调用了第二个API。
如果第二个API出现错误,我会在我的服务层中引发异常:
var response = await httpClient.SendAsync(request); //call second API
if (!response.IsSuccessStatusCode)
{
//return HTTP response with StatusCode = X, if response.StatusCode == X
throw new HttpRequestException(await response.Content.ReadAsStringAsync());
//this always returns 400
}
如何抛出异常,该异常将在第二个API调用中返回具有相同状态代码的响应?
如果我使用HttpRequestException
,即使response
对象具有StatusCode = 500
,它将始终返回400。
编辑:第一个API端点如下所示:
public async Task<ActionResult<HttpResponseMessage>> CreateTenancy([FromBody]TenancyRequest tenancy)
{
//Make some calls...
return Created(string.Empty, new { TenancyID = newTenancyExternalId });
}
第二个API端点看起来像这样:
[HttpPost]
public IHttpActionResult CreateTenancy([FromBody]TenancyDTO tenancyDTO)
{
var tenancy = GetTenancy();
return Created(string.Empty, tenancy);
}
我已经尝试过使用throw new HttpResponseException(response);
,但这会删除描述性的异常消息,有效负载最终会像这样:
{
"Code": 500,
"CorrelationId": "2df08016-e5e3-434a-9136-6824495ed907",
"DateUtc": "2020-01-30T02:02:48.4428978Z",
"ErrorMessage": "Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.",
"ErrorType": "InternalServerError"
}
我想将ErrorMessage
值保留在原始有效负载中:
{
"Code": 400,
"CorrelationId": "ff9466b4-8c80-4dab-b5d7-9bba1355a567",
"DateUtc": "2020-01-30T03:05:13.2397543Z",
"ErrorMessage": "\"Specified cast is not valid.\"",
"ErrorType": "BadRequest"
}
您可以简单地进行API调用并将其响应代码复制到与IStatusCodeActionResult
兼容的文件中。
引发自定义异常的替代方法。创建类似的东西>
public class ApiCallException : Exception { public APiCallException(int statusCode, ...) { ApiStatusCode = statusCode; } int ApiStatusCode { get; } ... }
并从您的API结果中复制状态代码,然后引发异常。
var response = await httpClient.SendAsync(request); //call second API if (!response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); throw new ApiCallException(500, content); }
然后您可以注册一个异常过滤器来调用
AddMvc
时处理结果。
services.AddMvc(options => options.Filters.Add<ExceptionFilter>());
ExceptionFilter
可能类似于
public class ExceptionFilter : IExceptionFilter
{
// ...
public void OnException(ExceptionContext context)
{
if (context.Exception is ApiCallException ace)
{
var returnObject = CreateReturnObjectSomehow();
context.Result = new ObjectResult(returnObject) { StatusCode = ace.StatusCode };
}
else
{
// do something else
}
}
}
我尝试了一些简单的操作,例如更改API端点的返回类型,并在出现错误时返回对象。否则,构建您自己的HttpResponseMessage并将其返回。下面的代码段使用文本,但是如果有的话,您可以使用序列化器序列化其他内容。