ServiceStack中如何在JSON映射到DTO前验证数据并捕获序列化错误
ServiceStack反序列化类型不匹配错误验证方案
ServiceStack原生支持捕获反序列化阶段的类型不匹配错误,你可以通过以下几种方式实现需求:
1. 全局拦截+返回与FluentValidation一致的错误格式
该方案可以直接在请求进入验证逻辑前捕获所有序列化错误,返回的响应结构和FluentValidation的错误结构完全一致,无需修改现有验证逻辑:
首先在AppHost的Configure方法中添加如下配置:
public override void Configure(Container container) { // 开启反序列化错误自动收集 JsConfig.AppendDeserializationErrors = true; // 注册全局请求过滤器,在验证执行前检查序列化错误 GlobalRequestFilters.Add((req, res, dto) => { // 存在序列化错误时直接构造和验证规则一致的错误返回 if (req.SerializationErrors.Any()) { var validationResult = new ValidationErrorResult(); foreach (var error in req.SerializationErrors) { validationResult.Errors.Add(new ValidationErrorField( errorCode: "TypeMismatch", fieldName: error.PropertyName, errorMessage: $"传入值「{error.AttemptedValue}」不符合字段类型要求" )); } res.WriteErrorResponse(req, validationResult); res.EndRequest(); } }); // 保留你现有的其他配置,包括FluentValidation的注册逻辑 }
2. 完全整合进FluentValidation逻辑
如果你希望序列化错误和业务验证错误统一走FluentValidation的处理流程,可以自定义验证基类实现:
// 自定义验证器基类,所有业务验证器继承该类即可 public abstract class SerializationErrorAwareValidator<T> : AbstractValidator<T> { protected SerializationErrorAwareValidator(IRequest request) { // 自动将序列化错误添加到验证失败列表 foreach (var err in request.SerializationErrors) { RuleFor(_ => _) .Custom((_, context) => { context.AddFailure(err.PropertyName, $"字段{err.PropertyName}类型错误,无效值:{err.AttemptedValue}"); }); } } }
使用时只需将你的业务验证器继承上述基类,并传入当前请求对象即可。
极简拦截方案(无需合并错误)
如果你不需要把序列化错误和FluentValidation错误合并,仅需要拦截非法请求直接返回错误,只需开启全局配置即可:
JsConfig.ThrowOnDeserializationError = true;
开启后反序列化遇到任何类型不匹配问题都会直接抛出400错误,不会进入后续的业务逻辑和验证流程。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

