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

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

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

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

非常感谢您的意见

【问题讨论】:

  • 找不到密钥应该引发 404

标签: c# asp.net-web-api odata


【解决方案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.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扩展方法有什么用,什么时候用?
    【解决方案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();    
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-18
        • 2019-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-31
        相关资源
        最近更新 更多