问题 在WebAPI C#中请求反序列化期间捕获异常#


我正在使用WebAPI v2.2,我正在使用[FromBody]属性将WebAPI反序列化到对象上。反序列化的目标类在内部方法上有[OnDeserialized]属性,如下所示:

[OnDeserialized]
internal void OnDeserialisedMethod(StreamingContext context) {
    // my method code
}

我知道这个方法中的代码存在问题,我已经逐步完成并找到了它。对我来说问题是我完全没有例外。发生的事情是这个方法被跳出来,异常似乎被忽略了。我的控制器操作被调用,我的目标对象未正确填充,因为此序列化方法未正确执行。

我的问题是;如何捕获WebAPI中反序列化期间发生的异常?


11343
2018-03-03 15:42


起源

asp.net/web-api/overview/error-handling/... - Jenish Rabadiya
我按照网页上的建议完成了但是它仍然没有取消异常?从ExceptionHandler类派生并注册 config.Services.Replace(typeof(IExceptionHandler), new Exceptions.MyExceptionHandler()); - Anupheaus
他们确实捕获了异常,但不是我想要的异常。它捕获了我的目标类没有正确填充的异常,它仍然没有看到OnDeserialized方法的任何异常。我需要在进入控制器操作方法之前捕获错误,这似乎是一个问题,它们似乎只是被忽略了。 - Anupheaus
哦对不起,这是我的坏事。它用于响应序列化而不是请求反序列化。 - Jenish Rabadiya
没有问题,我已经将标题更新为州请求反序列化,因为我认为这将使其更加清晰。 - Anupheaus


答案:


我已经编写了一个过滤器(如各种注释中所建议的),它检查ModelState并在发生序列化错误时抛出异常。但要注意,这可能不仅包含序列化异常 - 可以通过在中指定具体的异常类型来调整 Select 声明。

public class ValidModelsOnlyFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid)
        {
            base.OnActionExecuting(actionContext);
        }
        else
        {
            var exceptions = new List<Exception>();

            foreach (var state in actionContext.ModelState)
            {
                if (state.Value.Errors.Count != 0)
                {
                    exceptions.AddRange(state.Value.Errors.Select(error => error.Exception));
                }
            }

            if (exceptions.Count > 0)
                throw new AggregateException(exceptions);
        }
    }
}

我建议在全局范围内绑定此过滤器。我真的无法理解为什么忽略反序列化异常应该没问题。


11
2018-04-12 13:58





我有完全相同的问题,并将您的问题加入书签,希望有人能提供解决方案。我认为使用ModelState隐含了重写JSON模型中的一些验证,但它只是起作用,事实上它很简单,做得很好。我没有必要修改模型,只需要修改控制器。

我的一个控制器的代码,StdResponse是用于在需要时提供响应的类(例如,在这种情况下):

[HttpPost]
public StdResponse Test([FromBody]StdRequest request)
{
    if (ModelState.IsValid)
    {
        //Work on the data from the request...
    }
    else
    {
        //Retrieve the exceptions raised during deserialization
        var errors = ModelState.SelectMany(v => v.Value.Errors.Select(e => e.Exception));

        List<String> messages = new List<string>();

        foreach (Exception e in errors)
        {
            messages.Add(e.GetType().ToString() + ": " + e.Message);
        }

        return new StdResponse(exchangeVersion, "null", ExecutionResponse.WithError("StdRequest invalid", messages));
    }
}

3
2017-10-05 14:02





你可以查一下 ModelState.IsValid 在你的控制器内。 如果“OnDeserialisedMethod”抛出异常(或任何其他模型验证失败),它将是 如果一切顺利,那将是真的。


2
2017-09-02 03:40