我試圖創建一個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時,我的web服務返回了一個HTML格式的404頁面。這導致response.ErrorException
屬性包含以下字符串:
引用未聲明的實體'nbsp'。第n行,位置m。
顯然,RestSharp嘗試將響應解析爲XML,即使內容類型爲text/html。也許我會爲此爲RestSharp提出問題。
當然,在生產,呼籲自己的服務時,你不應該得到一個404,但我想這個客戶是徹底的和可重複使用的。
因此,有兩種解決方案,我能想到的:
- 檢查狀態代碼並顯示描述
- 確保服務返回一個錯誤的對象,你可以分析
前很容易完成。在HandleErrorResponse()
我建立結果信息(用戶呈現的)和基於狀態碼的數值錯誤字符串(爲loggable):
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>
,我
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;
}
}
可
set up an exception filter and a NotFound route在
ResultMessage
屬性與錯誤或異常信息返回一個可分析的響應模型
這樣從我服務的響應總是可以通過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);
}