【问题标题】:How to handle exceptions in Odata V4 client?如何处理 Odata V4 客户端中的异常?
【发布时间】:2016-01-27 06:35:35
【问题描述】:

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() 方法中以适当的方式处理异常,同时保存更改。

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

最后,我只想向最终用户显示从服务器发送的错误消息。 例子: “产品类别为必填项。”

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

请帮帮我。

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

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

    • 拦截您的自定义异常:创建自定义ExceptionFilterAttribute 来拦截您抛出的异常。覆盖 OnException(HttpActionExecutedContext filterContext) 您将可以访问异常,并检查它,您将能够构建正确的 OdataError

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

      公共覆盖无效 OnException(HttpActionExecutedContext filterContext) { 异常 ex = filterContext.Exception; HttpRequestMessage currentRequest = filterContext.Request; if (filterContext.Exception.GetType() == typeof(YourCustomValidationException)) { var oDataError = 新 ODataError() { ErrorCode = "invalidModel", Message = "您的模型无效。", 内部错误 = 新 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 中为所有 API 控制器设置过滤器,config.Filters.Add(...);

    您可以在here 中找到有关所有这些的更多信息。最后,对于 ASP.Net Web API,无论有无 OData,错误和异常处理都是一样的;不同之处在于,如果您有 OData API,则应该以 OData 样式返回错误。

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

    【讨论】:

      猜你喜欢
      • 2015-08-18
      • 2016-11-22
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 2015-04-26
      • 1970-01-01
      相关资源
      最近更新 更多