参考:
https://fluentvalidation.net/webapi
https://blog.csdn.net/qq289523052/article/details/23739243
1、安装FluentValidation.WebApi包
2、安装Autofac.WebApi包
3、自定义ValidatorFactory
public class ModelValidatorFactory : IValidatorFactory
{
// WebApi配置
private HttpConfiguration _config;
public ModelValidatorFactory(HttpConfiguration config)
{
_config = config;
}
public IValidator GetValidator(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (!typeof(IDtoVerify).IsAssignableFrom(type))
{
return null;
}
// WebAPI
return _config.DependencyResolver.GetService(typeof(IValidator<>).MakeGenericType(type)) as IValidator;
}
public IValidator<T> GetValidator<T>()
{
return _config.DependencyResolver.GetService(typeof(IValidator<T>)) as IValidator<T>;
}
}
4、定义全局过滤器
public class ModelVerifyFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var parameters = actionContext.ActionDescriptor.GetParameters();
if (parameters == null)
{
base.OnActionExecuting(actionContext);
return;
}
if (!actionContext.ModelState.IsValid)
{
if (parameters.Any(x => typeof(IDtoVerify).IsAssignableFrom(x.ParameterType)))
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
return;
}
else
{
base.OnActionExecuting(actionContext);
return;
}
}
else
{
var verifyParameter = parameters.Where(x => typeof(IDtoVerify).IsAssignableFrom(x.ParameterType));
if (verifyParameter == null || verifyParameter.Count() < 1)
{
base.OnActionExecuting(actionContext);
return;
}
else
{
foreach (var p in verifyParameter)
{
if (actionContext.ActionArguments.ContainsKey(p.ParameterName))
{
if (actionContext.ActionArguments[p.ParameterName] == null)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "实体不能为空!");
return;
}
}
}
base.OnActionExecuting(actionContext);
}
}
}
}
5、Autofac注册
public class IocConfig
{
public static IContainer IOCContainer;
public static void RegisterDependencies()
{
//创建autofac管理注册类的容器实例
var builder = new ContainerBuilder();
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
builder.RegisterAssemblyTypes(assemblies).InstancePerLifetimeScope();
// AsImplementedInterfaces以实现的接口注册,可以IValidator<Model> 创建,但不能用ModelDtoVerify创建
AssemblyScanner.FindValidatorsInAssemblies(assemblies)
.ForEach(x =>
builder.RegisterType(x.ValidatorType).AsImplementedInterfaces().InstancePerLifetimeScope()
);
//生成具体的实例
var container = builder.Build();
IocConfig.IOCContainer = container;
// webApi部分注册
HttpConfiguration config = GlobalConfiguration.Configuration;
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
6、注册依赖
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// Autofac注册依赖
IocConfig.RegisterDependencies();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
// 省略
}
}
7、webapi配置
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.Filters.Add(new ModelVerifyFilter());
//...
// 自定义验证Factory
FluentValidationModelValidatorProvider.Configure(config, provider =>
{
provider.ValidatorFactory = new ModelValidatorFactory(config);
});
}
}
8、注意,对于需要注入的类,访问级别设为:public,否则可能会报”类未注册“
9、对于验证类,如果在别外的dll或者空间中调用,访问级别也必须设为:public,否则验证总是返回true
//如果没有public,在其他dll或者空间调用时,不会执行下面的代码
//class ChangePwdDtoVerify:AbstractValidator<ChangePwdDto>
public class ChangePwdDtoVerify:AbstractValidator<ChangePwdDto>
{
public ChangePwdDtoVerify()
{
RuleFor(x => x.OldPassword)
.NotEmpty().WithMessage("旧密码不能为空");
RuleFor(x => x.NewPassword)
.NotEmpty().WithMessage("新密码不能为空");
}
}
完整代码下载地址:https://download.csdn.net/download/xinshun/11306766