2016-01-27 118 views
1

Asp.Net的Web API的OData控制器动作:如何处理Odata V4客户端中的异常?

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 class有什么用?这会帮助我吗?

请帮帮我。

回答

2

如果我理解的很好,您想拦截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

    在这里你应该用错误请求HTTP状态代码和创建ODataError作为有效载荷返回HttpResponseMessage。由于非常简单的代码示例(你可以看到,这将取决于你如何建立你的自定义异常):

     
    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每次请求到达您的控制器时。可以装饰你的行动,控制器,也可以为您的所有API控制器过滤器在WebApiConfig,用config.Filters.Add(...);

您可以找到有关here所有这些详细信息。最后,错误和异常处理对于使用或不使用OData的ASP.Net Web API是一样的;不同的是,如果你有一个OData API,你应该在OData风格中返回错误。

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

相关问题