ASP.NET Odata Web API 的错误处理

Posted

技术标签:

【中文标题】ASP.NET Odata Web API 的错误处理【英文标题】:Error Handling for ASP.NET Odata Web API 【发布时间】:2013-10-23 17:17:45 【问题描述】:

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

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

例如:如果输入请求有一个无效的键,想返回一个 400 的 HttpResponseCode 并且内容应该有类似于引发异常的错误细节。

非常感谢您的意见

【问题讨论】:

找不到密钥应该引发 404 【参考方案1】:

使用HttpResponseException, 例如throw new HttpResponseException(HttpStatusCode.NotFound);. 详情可见here。

【讨论】:

【参考方案2】:

OData(至少从 v3 开始)使用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.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);
    

【讨论】:

CreateODataErrorResponse扩展方法有什么用,什么时候用?【参考方案3】:

检查CreateErrorResponse in the OData documentation。 Microsoft.AspNet.OData 中使用的命名空间。我让我的代码使用它。

【讨论】:

【参考方案4】:

对于带有 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();    

【讨论】:

以上是关于ASP.NET Odata Web API 的错误处理的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Web API 实现中将数组传递给 OData 函数?

使用 OData 的 ASP.Net Core Web API 实现对于单个实体 URI 失败

Asp.Net Web API 2第十八课——Working with Entity Relations in OData

在 ASP.NET Web API 控制器的 nunit 测试中实例化新的 System.Web.Http.OData.Query.ODataQueryOptions

Asp.Net MVC4 Web API - 我们是不是需要 OData 来构建快速查询服务

无法使用 ASP.NET (MVC 4) Web API OData Prerelease 加载文件或程序集 System.Net.Http,版本 = 4.0.0.0