ASP.NET Odata Web API 的错误处理

19

我想知道在ODataController中引发异常的最佳实践是什么。

如果在方法中引发异常,默认情况下将其转换为500响应代码,并且内容具有关于错误的详细信息。 我希望明确响应代码,并在无效密钥的情况下发送400。

例如:如果输入请求具有无效密钥,希望返回Http响应代码400,并且内容应类似于引发异常时的错误详细信息。

非常感谢您的建议!


关键字未找到应引发404错误。 - qujck
4个回答

27

OData(至少从v3开始)使用特定的JSON格式来表示错误:specific 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.ODataErrorMicrosoft.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);
    }
}

CreateODataErrorResponse 扩展方法的用途是什么?我们应该在什么情况下使用它? - Rahul

3

对于使用OData的ASP.NET Core应用程序,请在Get方法中将EnableQueryAttribute替换为自定义属性,该属性捕获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();    
}

1
使用 HttpResponseException,例如 throw new HttpResponseException(HttpStatusCode.NotFound);。详情请参见此处

0

1
这似乎在8.0中不存在。 - starchild

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接