gpt4 book ai didi

c# - 如何在 HttpClient response.ReasonPhrase 中获取真正的错误消息?

转载 作者:行者123 更新时间:2023-11-30 14:48:51 25 4
gpt4 key购买 nike

我的设置

我有 2 个 WebApi 项目,流程如下:

  1. 用户API 1发出请求
  2. API 1 代表用户向 API 2 发出请求(使用 HttpClient)。

using (var client = new HttpClient())
{
client.SetBearerToken(token);

string endpoint = PbbSettings.Identity.Users.Delete.Replace("{userId}", userId);

// Attempt deletion of the user
using (var response = await client.DeleteAsync(endpoint))
{
// Throw exception if not succeeded
EnsureSuccess(response);
}
}

问题

因此控制和信息流工作正常。问题是,当 API 2 响应错误时,response.ReasonPhrase 显示“Bad Request”或“Internal Server Error”,而不是我在异常中设置的消息.

一整天都在吐血。有什么见解吗?

更多信息(TLDR)

为清楚起见,我所有的 API 都注册了一个全局异常过滤器来处理错误:

public class RepositoryExceptionsHandlerAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
HandleException(context);

base.OnException(context);
}

public override Task OnExceptionAsync(HttpActionExecutedContext context, CancellationToken cancellationToken)
{
HandleException(context);

return base.OnExceptionAsync(context, cancellationToken);
}

/// <summary>
/// Recognizes common repository exceptions and if necessary creates a response and updates the context.
/// </summary>
/// <param name="context">The context in which the exception was thrown.</param>
private void HandleException(HttpActionExecutedContext context)
{
var response = CreateResponse(context.Request, context.Exception);

if (response != null)
context.Response = response;
}

/// <summary>
/// Recognizes common repository exceptions and creates a corresponding error response.
/// </summary>
/// <param name="request">The request to which the response should be created.</param>
/// <param name="ex">The exception to handle.</param>
/// <returns>An error response containing the status code and exception data, or null if this is not a common exception.</returns>
private HttpResponseMessage CreateResponse(HttpRequestMessage request, Exception ex)
{
string message = ex.Message;

if (ex is KeyNotFoundException) return request.CreateErrorResponse(HttpStatusCode.NotFound, message);
if (ex is ArgumentException) return request.CreateErrorResponse(HttpStatusCode.BadRequest, message);
if (ex is InvalidOperationException) return request.CreateErrorResponse(HttpStatusCode.BadRequest, message);
if (ex is UnauthorizedAccessException) return request.CreateErrorResponse(HttpStatusCode.Unauthorized, message);
#if !DEBUG
// For security reasons, when an exception is not handled the system should return a general error, not exposing the real error information
// In development time, the programmer will need the details of the error, so this general message is disabled.
request.CreateErrorResponse(HttpStatusCode.InternalServerError, Errors.InternalServerError);
#endif

return null;
}
}

这在用户API 1 之间工作正常。但是当 API 1API 2 执行它们的操作时,响应创建会忽略我输入的消息并将状态设置为原因。

最佳答案

新的 CreateResponse() 方法:

    /// <summary>
/// Recognizes common repository exceptions and creates a corresponding error response.
/// </summary>
/// <param name="request">The request to which the response should be created.</param>
/// <param name="ex">The exception to handle.</param>
/// <returns>An error response containing the status code and exception data, or null if this is not a common exception.</returns>
private HttpResponseMessage CreateResponse(HttpRequestMessage request, Exception ex)
{
string message = ex.Message;

HttpStatusCode code = 0;

if (ex is KeyNotFoundException) code = HttpStatusCode.NotFound;
else if (ex is ArgumentException) code = HttpStatusCode.BadRequest;
else if (ex is InvalidOperationException) code = HttpStatusCode.BadRequest;
else if (ex is UnauthorizedAccessException) code = HttpStatusCode.Unauthorized;
else if (ex is HttpException)
{
// HttpExceptions are thrown when request between IdentityServer and the API server have failed.
// IdentityServer has generated an error, the API server received it and now it needs to relay it back to the client.
var httpException = (HttpException) ex;

code = (HttpStatusCode) httpException.GetHttpCode();
message = httpException.Message;
}
else
{
code = HttpStatusCode.InternalServerError;

// For security reasons, when an exception is not handled the system should return a general error, not exposing the real error information
// In development time, the programmer will need the details of the error, so this general message is disabled.
#if DEBUG
message = ex.Message;
#else
message = Errors.InternalServerError;
#endif
}

// For some reason the request.CreateErrorResponse() method ignores the message given to it and parses its own message.
// The error response is constructed manually.
return CreateErrorResponse(request, code, message);
}

private HttpResponseMessage CreateErrorResponse(HttpRequestMessage request, HttpStatusCode code, string message)
{
var content = new { Message = message };

return new HttpResponseMessage(code)
{
ReasonPhrase = message,
RequestMessage = request,
Content = new ObjectContent(content.GetType(), content, new JsonMediaTypeFormatter())
};
}
}

希望这只是节省了某人的一天...;)

关于c# - 如何在 HttpClient response.ReasonPhrase 中获取真正的错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40136132/

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