我很想知道在 ODataController 中引发异常的最佳实践是什么。
如果您在方法中引发异常,则默认情况下将其转换为响应代码 500,并且内容包含有关错误的详细信息。我想明确响应代码并在密钥无效的情况下发送 400。
例如:如果输入请求有一个无效的键,想返回一个 400 的 HttpResponseCode 并且内容应该有类似于引发异常的错误细节。
非常感谢您的投入
我很想知道在 ODataController 中引发异常的最佳实践是什么。
如果您在方法中引发异常,则默认情况下将其转换为响应代码 500,并且内容包含有关错误的详细信息。我想明确响应代码并在密钥无效的情况下发送 400。
例如:如果输入请求有一个无效的键,想返回一个 400 的 HttpResponseCode 并且内容应该有类似于引发异常的错误细节。
非常感谢您的投入
OData(至少从 v3 开始)使用特定的 json来表示错误:
{
"error": {
"code": "A custom error code",
"message": {
"lang": "en-us",
"value": "A custom long message for the user."
},
"innererror": {
"trace": [...],
"context": {...}
}
}
}
Microsoft .Net 包含Microsoft.Data.OData.ODataError和Microsoft.Data.OData.ODataInnerError类以在服务器端形成 OData 错误。
要形成正确的 OData 错误响应 ( HttpResponseMessage ),其中包含错误详细信息,您可以:
1) 使用System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateErrorResponse方法在控制器的操作中形成并返回 HttpResponseMessage
return Request.CreateErrorResponse(HttpStatusCode.Conflict, new ODataError { ErrorCode="...", Message="...", MessageLanguage="..." }));
2) 使用与创建 HttpResponseMessage 相同的方法抛出 HttpResponseException
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.NotFound, new ODataError { ErrorCode="...", Message="...", MessageLanguage="..." }));
3) 抛出自定义类型异常并使用 Web Api 操作过滤器对其进行转换
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is CustomException)
{
var e = (CustomException)context.Exception;
var response = context.Request.CreateErrorResponse(e.StatusCode, new ODataError
{
ErrorCode = e.StatusCodeString,
Message = e.Message,
MessageLanguage = e.MessageLanguage
});
context.Response = response;
}
else
base.OnException(context);
}
}
Use HttpResponseException
,
e.g. throw new HttpResponseException(HttpStatusCode.NotFound);
.
Details can be found here.
对于带有 OData 的 ASP.NET Core,EnableQueryAttribute
请将方法上的 替换为捕获并引发自定义异常Get
的自定义属性。ODataException
在大多数情况下,这允许标准错误处理按预期介入。最初在https://github.com/OData/WebApi/issues/1898找到了这个解决方案。
对于您的自定义属性,请使用以下内容:
public class CustomEnableQueryAttribute : EnableQueryAttribute
{
public override void ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)
{
try
{
base.ValidateQuery(request, queryOptions);
}
catch (ODataException e)
{
throw new CustomException(e.Message, e){UserMessage = "Invalid OData query."};
}
}
}
在您的Get
方法上,使用如下内容:
[HttpGet, CustomEnableQuery]
public virtual IQueryable<TDomainDto> Get()
{
return Repository.Get();
}
检查OData 文档中的 CreateErrorResponse。Microsoft.AspNet.OData 中使用的命名空间。我让我的代码使用它。