在 WebAPI C# 中请求反序列化期间捕获异常
Capture exception during request deserialization in WebAPI C#
我正在使用 WebAPI v2.2,我正在让 WebAPI 使用 [FromBody] 属性将 JSON 反序列化到一个对象上。反序列化的目标 class 在内部方法上有一个 [OnDeserialized] 属性,如下所示:
[OnDeserialized]
internal void OnDeserialisedMethod(StreamingContext context) {
// my method code
}
我知道这个方法中的代码确实有问题,我已经逐步检查并找到了它。对我来说,问题是我一点也不例外。发生的事情是这个方法被跳出并且异常似乎被忽略了。由于未正确执行此序列化方法,我的控制器操作被调用并且我的目标对象未正确填充。
我的问题是;如何捕获 WebAPI 反序列化期间发生的异常?
您可以在控制器中查看 ModelState.IsValid。
如果 "OnDeserialisedMethod" 抛出异常(或任何其他模型验证失败),它将是 false,如果一切成功,它将是 true。
我遇到了完全相同的问题,并将您的问题加入书签,希望有人能提供解决方案。我认为使用 ModelState 意味着在 JSON 模型中重写一些验证,但它确实有效,事实上它很简单而且做得很好。我不需要修改模型,只需要修改控制器。
我的代码来自我的一个控制器,StdResponse 是 class 用于在需要时提供响应的详细信息(例如,在本例中):
[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 并在确实发生序列化错误时抛出异常。但是请注意,这可能不仅仅包含序列化异常 - 可以通过在 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);
}
}
}
我建议在全局范围内绑定此过滤器。我真的无法理解为什么忽略反序列化异常应该没问题。
我正在使用 WebAPI v2.2,我正在让 WebAPI 使用 [FromBody] 属性将 JSON 反序列化到一个对象上。反序列化的目标 class 在内部方法上有一个 [OnDeserialized] 属性,如下所示:
[OnDeserialized]
internal void OnDeserialisedMethod(StreamingContext context) {
// my method code
}
我知道这个方法中的代码确实有问题,我已经逐步检查并找到了它。对我来说,问题是我一点也不例外。发生的事情是这个方法被跳出并且异常似乎被忽略了。由于未正确执行此序列化方法,我的控制器操作被调用并且我的目标对象未正确填充。
我的问题是;如何捕获 WebAPI 反序列化期间发生的异常?
您可以在控制器中查看 ModelState.IsValid。 如果 "OnDeserialisedMethod" 抛出异常(或任何其他模型验证失败),它将是 false,如果一切成功,它将是 true。
我遇到了完全相同的问题,并将您的问题加入书签,希望有人能提供解决方案。我认为使用 ModelState 意味着在 JSON 模型中重写一些验证,但它确实有效,事实上它很简单而且做得很好。我不需要修改模型,只需要修改控制器。
我的代码来自我的一个控制器,StdResponse 是 class 用于在需要时提供响应的详细信息(例如,在本例中):
[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 并在确实发生序列化错误时抛出异常。但是请注意,这可能不仅仅包含序列化异常 - 可以通过在 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);
}
}
}
我建议在全局范围内绑定此过滤器。我真的无法理解为什么忽略反序列化异常应该没问题。