如何处理Odata V4客户端中的异常?

时间:2016-01-27 06:35:36

标签: asp.net odata asp.net-web-api2 dataservice odata-v4

Asp.Net Web API Odata控制器操作:

public async Task<IHttpActionResult> Post(Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Created(product);
}

Odata客户代码: (Odata v4客户端代码生成器v4)

static void AddProduct(Default.Container container, ProductService.Models.Product product)
{
    container.AddToProducts(product);
    var serviceResponse = container.SaveChanges();
    foreach (var operationResponse in serviceResponse)
    {
        Console.WriteLine("Response: {0}", operationResponse.StatusCode);
    }
}

我想在AddProducts()方法中以适当的方式处理异常,同时保存更改。

如何处理从服务器ModelState发送的return BadRequest(ModelState);错误?

最后,我只想向服务器发送的最终用途显示错误消息。 例: “产品类别是必需的。”

ODataException课有什么用?这对我有帮助吗?

请帮帮我。

1 个答案:

答案 0 :(得分:4)

如果我理解得很好,你想拦截ModelState无效,并自定义向用户显示的OData错误。

如果您只是希望在返回的有效负载中显示无效模型的错误,您可以使用:

if (!ModelState.IsValid)
{
    return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}

如果您想完全控制所显示的异常处理和消息,我建议您为此完成以下几个操作点:

  • 拦截ModelState无效:您可以使用自定义ActionFilterAttribute执行此操作。在那里,您可以覆盖方法OnActionExecuting(HttpActionContext actionContext)。您可以访问ModelStateactionContext.ModelState,检查它是否有效,检查有错误的字段,检查这些错误的性质以及为这些错误生成的消息等.ModelState可能不是由于不同的原因有效,例如不同于预期的类型,不符合DataAnnotations等指定的要求。您可以在here中查看有关模型验证的更多信息。对于您的情况,我猜产品实体将在类别字段中具有必需的数据注释。

    检查完所有错误后,您可以使用所需的消息抛出错误/错误列​​表的自定义异常。这是必要的,以便以后拦截您的自定义异常,并能够在错误有效负载中返回您的自定义消息。

  • 拦截您的自定义异常:创建自定义ExceptionFilterAttribute以拦截您抛出的异常。压倒了 OnException(HttpActionExecutedContext filterContext)您将有权访问该异常,并检查该异常,您将能够构建正确的OdataError

    在这里,您应该返回带有BadRequest http状态代码的HttpResponseMessage和创建的ODataError作为有效负载。作为一个非常简单的代码示例(您可以看到它将取决于您如何构建自定义异常):

    public override void OnException(HttpActionExecutedContext filterContext)
    {
        Exception ex = filterContext.Exception;
        HttpRequestMessage currentRequest = filterContext.Request;
        if (filterContext.Exception.GetType() == typeof(YourCustomValidationException))
        {
            var oDataError = new ODataError()
            {
                ErrorCode = "invalidModel",
                Message = "Your model is not valid.",
                InnerError = new ODataInnerError()
                {
                    TypeName = ex.TheEntityThatHasErrors
                },
            };

    foreach (var validationError in ex.ValidationErrors) { oDataError.InnerError.Message += validationError + ", "; } HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest); response.RequestMessage = currentRequest; response.Content = new StringContent(JsonConvert.SerializeObject(oDataError)); filterContext.Response = response; } }
  • 最后,每次请求到达控制器时,您都必须设置自定义ActionFilterAttribute和自定义ErrorFilterAttribute。您可以装饰您的操作,控制器,或者可以使用WebApiConfig

  • config.Filters.Add(...);中为所有API控制器设置过滤器

您可以在here中找到有关所有这些内容的更多信息。最后,ASP.Net Web API的错误和异常处理是相同的,有或没有OData;区别在于,如果您有OData API,则应该以OData样式返回错误。

希望所有这些信息都是可以理解的,并以某种方式帮助你。