简体   繁体   English

ASP.NET Odata Web API 的错误处理

[英]Error Handling for ASP.NET Odata Web API

I'm interested in knowing what are the best practices being followed to raise exceptions in the ODataController.我很想知道在 ODataController 中引发异常的最佳实践是什么。

If you raise an exception in the method it is translated to response code of 500 by default and the content has details on the error.如果在方法中引发异常,默认情况下它会转换为响应代码 500,并且内容包含有关错误的详细信息。 I would like to be explicit of the response code and send 400 in cases of invalid key.我想明确响应代码并在密钥无效的情况下发送 400。

For example: If the input request has an invalid key would like to return a HttpResponseCode of 400 and content should have the error details similar to raising an exception.例如:如果输入请求有一个无效的键想要返回 400 的 HttpResponseCode 并且内容应该具有类似于引发异常的错误详细信息。

Thanks a lot for your inputs非常感谢您的投入

OData (at least since v3) uses specific json to represent errors: 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 contains Microsoft.Data.OData.ODataError and Microsoft.Data.OData.ODataInnerError classes to form OData error on a server side. Microsoft .Net 包含Microsoft.Data.OData.ODataErrorMicrosoft.Data.OData.ODataInnerError类以在服务器端形成 OData 错误。

To form proper OData error response ( HttpResponseMessage ), that contains error details you can:要形成正确的 OData 错误响应 ( HttpResponseMessage ),其中包含错误详细信息,您可以:

1) form and return HttpResponseMessage in controller's action using System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateErrorResponse method 1) 使用System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateErrorResponse方法在控制器的动作中形成并返回 HttpResponseMessage

return Request.CreateErrorResponse(HttpStatusCode.Conflict, new ODataError { ErrorCode="...", Message="...", MessageLanguage="..." }));

2) throw HttpResponseException using the same method for creating HttpResponseMessage 2) 使用与创建 HttpResponseMessage 相同的方法抛出 HttpResponseException

throw new HttpResponseException(
    Request.CreateErrorResponse(HttpStatusCode.NotFound,  new ODataError { ErrorCode="...", Message="...", MessageLanguage="..." }));

3) throw custom typed exception and convert it using Web Api action filters 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 ,使用HttpResponseException
eg throw new HttpResponseException(HttpStatusCode.NotFound);例如throw new HttpResponseException(HttpStatusCode.NotFound); . .
Details can be found here .可在此处找到详细信息。

Check CreateErrorResponse in the OData documentation .检查OData 文档中的 CreateErrorResponse The namespace to the used in Microsoft.AspNet.OData. Microsoft.AspNet.OData 中使用的命名空间。 I got my code working using this.我让我的代码使用这个工作。

For ASP.NET Core with OData, replace the EnableQueryAttribute on your Get method with a custom attribute that catches ODataException and throws a custom exception.对于ASP.NET核心与OData的,更换EnableQueryAttributeGet与捕获的自定义属性的方法ODataException并抛出一个自定义异常。 In most cases, this allows standard error handling to step in as expected.在大多数情况下,这允许标准错误处理按预期介入。 Originally found this solution at https://github.com/OData/WebApi/issues/1898 .最初在https://github.com/OData/WebApi/issues/1898找到了这个解决方案。

For your custom attribute, use something like the following:对于您的自定义属性,请使用以下内容:

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."};
        }
    }
}

On your Get method, use something like the following:在您的Get方法中,使用以下内容:

[HttpGet, CustomEnableQuery]
public virtual IQueryable<TDomainDto> Get()
{
    return Repository.Get();    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM