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

本文关键字:捕获异常 反序列化 请求 WebAPI | 更新日期: 2024-09-25 02:55:39

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

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

事实上,我知道这个方法中的代码有问题,我已经仔细检查并找到了它。对我来说,问题是我一点也不例外。发生的情况是,这个方法被跳出,并且异常似乎被忽略了。我的控制器操作被调用,我的目标对象没有正确填充,因为这个串行化方法没有正确执行。

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

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

我已经编写了一个过滤器(如各种注释中所建议的),它检查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);
        }
    }
}

我建议将此筛选器绑定到全局范围。我真的无法理解为什么忽略反序列化异常是可以的。

我遇到了完全相同的问题,并将您的问题添加到书签中,希望有人能提供解决方案。我认为使用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));
    }
}

您可以在控制器内检查ModelState.IsValid。如果"OnDeserializedMethod"抛出异常(或任何其他模型验证失败),则为false,如果一切成功,则为true。