我的webapi中有以下方法。我希望能够将异常传递给post man并查看 错误。我尝试使用"返回BadRequest(ex.Message);"由于方法的返回类型,我得到了错误。
如何更正此问题,以便我可以返回实际的错误消息?
// GET api/Articles/News
public IEnumerable<ArticlesDto> Get(string category)
{
IEnumerable<ArticlesDto> articlesByCategory = null;
try
{
if (category == null)
{
}
articlesByCategory = _articlesrepository.Find(category);
}
catch(Exception ex)
{
return BadRequest(ex.Message);
}
return articlesByCategory;
}
答案 0 :(得分:2)
您正在做的事情存在一些问题。让我们首先回顾一下,然后我们将采用更好的方法。
<强>问题强>
static IEnumerable<T> OrderByEnumerable<T>(this IEnumerable<T> data, IEnumerable<string> data2)
{
return data.Zip(data2, (x, y) => //
}
的异常,然后告诉客户端他们的请求是一个错误的请求。如果您有Exception
,db not found异常,或DivideByZeroException
或任何其他异常,您将告诉客户端他们的请求是坏的。这显然不是真的。从Web API返回响应
返回域对象(或DTO)很好,但如果您希望对响应进行更精细的控制,则使用InvalidOperationException
。这是一个examplef(请阅读代码中的注释以获取更多信息):
HttpResponseMessage
Web API 2
使用Web API 2,您可以这样做,这样更容易,更清洁。请根据您的要求更改代码。
public HttpResponseMessage Get(string category)
{
// Step 1: First check the obvious issues
if (string.IsNullOrWhiteSpace(category))
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
try
{
// The client has sent us a category. Now we have to do our best to
// satisfy the request.
// Step 2: Optional Step: First check to see if we have the category
string cat = _categoryRepository.Get(category);
if (string.IsNullOrWhiteSpace(cat))
{
var message = new HttpResponseMessage(HttpStatusCode.NotFound);
message.Content = new StringContent($"The category with the name {category} was not found.");
throw new HttpResponseException(message);
}
// Step 3: Category exists so let's return the products
IEnumerable<ArticlesDto> articlesByCategory = _articlesrepository.Find(category);
// Even if the list is empty, we can still return it to tell
// the client 0 items were found
// for the category.
return Request.CreateResponse(HttpStatusCode.OK, articlesByCategory);
}
catch (Exception ex)
{
// Something went wrong on our side (NOT the client's fault). So we need to:
// 1. Log the error so we can troubleshoot it later
// 2. Let the client know it is not their fault but our fault.
return Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
答案 1 :(得分:0)
可能有其他一些方法可以做到这一点(我不是自称是ASP.Net核心专家),但我已经通过以下方式解决了这个问题。首先,定义一个自定义异常类。目的是你可以实际抛出,而不考虑任何控制器方法返回类型。此外,抛出异常会使控制流更加结构化。
public class CustomApiException : Exception
{
/// <summary>
/// Optional application-specific error code returned to the client.
/// </summary>
public int? ApplicationErrorCode { get; private set; } = null;
/// <summary>
/// HTTP status code returned to the client.
/// </summary>
public HttpStatusCode HttpStatusCode { get; private set; } = HttpStatusCode.BadRequest;
public CustomApiException() : base() { }
public CustomApiException(string message) : base(message) { }
public CustomApiException(string message, HttpStatusCode httpStatusCode) : base(message)
{
HttpStatusCode = httpStatusCode;
}
public CustomApiException(string message, HttpStatusCode httpStatusCode, int? applicationErrorCode) : base(message)
{
HttpStatusCode = httpStatusCode;
ApplicationErrorCode = applicationErrorCode;
}
public CustomApiException(string message, int? applicationErrorCode) : base(message)
{
ApplicationErrorCode = applicationErrorCode;
}
}
然后定义自定义ExceptionFilterAttribute。请注意,此复制/粘贴代码段的功能比您要求的要多一些。例如。根据开发与生产的不同,它将包含异常的整个堆栈跟踪(实际上是任何异常,而不仅仅是CustomApiException)。
// todo: turn into async filter.
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly ILogger<ApiExceptionFilterAttribute> _logger;
private readonly IHostingEnvironment _env;
public ApiExceptionFilterAttribute(ILogger<ApiExceptionFilterAttribute> logger, IHostingEnvironment env)
{
_logger = logger;
_env = env;
}
public override void OnException(ExceptionContext context)
{
_logger.LogError(new EventId(0), context.Exception, context.Exception.Message);
dynamic errObject = new JObject();
HttpStatusCode statusCode = HttpStatusCode.InternalServerError; // use 500 unless the API says it's a client error
if (context.Exception.GetType() == typeof(CustomApiException))
{
CustomApiException customEx = (CustomApiException)context.Exception;
if (customEx.ApplicationErrorCode != null) errObject.errorCode = customEx.ApplicationErrorCode;
errObject.errorMessage = customEx.Message;
statusCode = customEx.HttpStatusCode;
}
if (_env.IsDevelopment())
{
errObject.errorMessage = context.Exception.Message;
errObject.type = context.Exception.GetType().ToString();
errObject.stackTrace = context.Exception.StackTrace;
}
JsonResult result = new JsonResult(errObject);
result.StatusCode = (int?)statusCode;
context.Result = result;
}
}
最后,将自定义ExceptionFilterAttribute添加到全局ConfigureServices方法。
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//...
// Add framework services.
services.AddMvc(options =>
{
options.Filters.Add(typeof(ApiExceptionFilterAttribute));
});
}
// ...
}
这是一些工作,但只有一次性工作,并且一旦你添加它就非常强大。如果我没记错的话,我的解决方案就是基于这个MS页面Exception Handling。如果您有其他问题,这可能会有所帮助。
答案 2 :(得分:0)
对于你的情况,我认为抛出HttpResponseException
HttpResponseMessage
包含异常消息可行。流动的代码片段已经过我的测试。
public IEnumerable<string> Get()
{
try
{
throw new InvalidOperationException("Invalid Operation");
}
catch(Exception ex)
{
var res = new HttpResponseMessage(HttpStatusCode.InternalServerError);
res.Content = new StringContent(ex.Message);
throw new HttpResponseException(res);
}
}
有关如何在WebAPI流程中处理异常的更多信息,请参阅this官方指南。希望它对你有所帮助。