gpt4 book ai didi

c# - 使用 RestSharp 时如何惯用地处理 HTTP 错误代码?

转载 作者:可可西里 更新时间:2023-11-01 03:00:20 24 4
gpt4 key购买 nike

我正在使用 RestSharp 构建一个 HTTP API 客户端,我注意到当服务器返回 HTTP 错误代码(401 未授权、404 未找到、500 内部服务器错误等)时,RestClient.Execute()不会抛出异常 - 相反我得到一个有效的 RestResponse.Data属性(property)。我不想在我的 API 客户端中手动检查每个可能的 HTTP 错误代码 - RestSharp 是否提供了将这些错误传递到我的客户端应用程序的更好方法?

再详细一点。 RestSharp 公开了一个 Response.ErrorException属性 - 如果 RestClient.Execute<T>()调用会导致任何异常,它将通过 ErrorException 暴露出来属性(property)而不是被扔掉。他们的文档包括以下示例:

// TwilioApi.cs
public class TwilioApi {
const string BaseUrl = "https://api.twilio.com/2008-08-01";

public T Execute<T>(RestRequest request) where T : new()
{
var client = new RestClient();
client.BaseUrl = BaseUrl;
client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment); // used on every request
var response = client.Execute<T>(request);

if (response.ErrorException != null)
{
const string message = "Error retrieving response. Check inner details for more info.";
var twilioException = new ApplicationException(message, response.ErrorException);
throw twilioException;
}
return response.Data;
}

}

我在我的代码中采用了该模式,但我的 API 服务器返回一个 401 Unauthorized但是 ErrorException 属性仍然为 null。我可以看到 RestResponse debug watch RestResponse.StatusCode 中的未授权状态代码和错误消息和 RestResponse.StatusDescription属性 - 但我很困惑为什么未经授权的响应不会导致 ErrorException正在填充的字段。

最佳答案

我在尝试为 RestSharp WebAPI 客户端创建通用错误处理程序时遇到了同样的问题。鉴于这些扩展方法:

public static class RestSharpExtensionMethods
{
public static bool IsSuccessful(this IRestResponse response)
{
return response.StatusCode.IsSuccessStatusCode()
&& response.ResponseStatus == ResponseStatus.Completed;
}

public static bool IsSuccessStatusCode(this HttpStatusCode responseCode)
{
int numericResponse = (int)responseCode;
return numericResponse >= 200
&& numericResponse <= 399;
}
}

我提出了一个要求反序列化响应的请求:

public async Task<ResponseModel<TResponse>> PerformRequestAsync<TResponse>(IRestRequest request)
{
var response = await _client.ExecuteTaskAsync<ResponseModel<TResponse>>(request);
ResponseModel<TResponse> responseData;

if (response.IsSuccessful())
{
responseData = response.Data;
}
else
{
string resultMessage = HandleErrorResponse<TResponse>(request, response);

responseData = new ResponseModel<TResponse>
{
Success = false,
ResultMessage = resultMessage
};
}

return responseData;
}

但是,在测试期间,我发现当我没有为这种情况配置错误处理时,我的网络服务在请求未映射的 URL 时返回 HTML 格式的 404 页面。这导致了 response.ErrorException属性包含以下字符串:

Reference to undeclared entity 'nbsp'. Line n, position m.

显然 RestSharp 试图将响应解析为 XML,即使内容类型是文本/html。也许我会为此向 RestSharp 提出问题。

当然,在生产中调用您自己的服务时,您永远不应该得到 404,但我希望这个客户端是彻底的和可重用的。

所以我想到了两种解决方案:

  • 检查状态码并显示描述
  • 确保服务返回一个您可以解析的错误对象

前者很容易完成。在 HandleErrorResponse()我根据状态代码的数值构建结果消息(用户可呈现)和错误字符串(可记录):

public string HandleErrorResponse(IRestRequest request, IRestResponse response)
{
string statusString = string.Format("{0} {1} - {2}", (int)response.StatusCode, response.StatusCode, response.StatusDescription);
string errorString = "Response status: " + statusString;

string resultMessage = "";
if (!response.StatusCode.IsScuccessStatusCode())
{
if (string.IsNullOrWhiteSpace(resultMessage))
{
resultMessage = "An error occurred while processing the request: "
+ response.StatusDescription;
}
}
if (response.ErrorException != null)
{
if (string.IsNullOrWhiteSpace(resultMessage))
{
resultMessage = "An exception occurred while processing the request: "
+ response.ErrorException.Message;
}
errorString += ", Exception: " + response.ErrorException;
}

// (other error handling here)

_logger.ErrorFormat("Error response: {0}", errorString);

return resultMessage;
}

现在我的 API 响应总是包含在 ResponseModel<T> 中我做的,我可以set up an exception filter and a NotFound routeResultMessage 中返回带有错误或异常消息的可解析响应模型属性:

public class HandleErrorAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
// (log context.Exception here)

context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, new ResponseModel<object>
{
Success = false,
ResultMessage = "An exception occurred while processing the request: " + context.Exception.Message
});
}
}

和:

public class ErrorController : ApiController
{
public HttpResponseMessage Handle404()
{
const string notFoundString = "The requested resource could not be found";

var responseMessage = Request.CreateResponse(HttpStatusCode.NotFound, new ResponseModel<object>
{
Success = false,
ResultMessage = notFoundString
});

responseMessage.ReasonPhrase = notFoundString;

return responseMessage;
}
}

这样我的服务的响应总是可以被 RestSharp 解析,我可以使用通用的日志记录方法:

public string HandleErrorResponse<TResponseModel>(IRestRequest request, IRestResponse<<ResponseModel<TResponseModel>> response)

并在 // (other error handling here) 处记录实际响应,如果可用:

if (response.Data != null && !string.IsNullOrWhiteSpace(response.Data.ResultMessage))
{
resultMessage = response.Data.ResultMessage;
errorString += string.Format(", Service response: \"{0}\"", response.Data.ResultMessage);
}

关于c# - 使用 RestSharp 时如何惯用地处理 HTTP 错误代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31516501/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com