因此,在帖子@nkosi左边对这个问题发表评论之后,我开始走上正确的道路(我认为),最终实现了一个基于
type filters
.
首先,我有一个需要在类型过滤器中实现的基本验证器模型:
public abstract class BaseViewModelValidator<TModel> : IAsyncActionFilter
where TModel : class
{
public async virtual Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// get the model to validate
if (context.ActionArguments["model"] is TModel model)
await this.ValidateAsync(model, context.ModelState);
else
throw new Exception($"View model of type `{context.ActionArguments["model"].GetType()}` found, type of `{typeof(TModel)}` is required.");
await next();
}
public abstract Task ValidateAsync(TModel model, ModelStateDictionary state);
}
然后,因为将其用作命名属性比将其用作命名属性要好得多
[TypeFilter(typeof(SomeActionFilter))]
,我创建了一个
TypeFilterAttribute
这样包装了我的基本验证器的实现:
public class DemoViewModelValidatorAttribute : TypeFilterAttribute
{
public DemoViewModelValidatorAttribute()
: base(typeof(DemoViewModelValidator))
{
}
internal class DemoViewModelValidator : BaseViewModelValidator<DemoViewModel>
{
private readonly ISomeService service;
// dependencies are injected here (assuming you've registered them in the start up)
public DemoViewModelValidator(ISomeService service) => this.service = service;
public async override Task ValidateAsync(DemoViewModel model, ModelStateDictionary state)
{
if (await this.service.CheckSomethingAsync(model))
state.AddModelError(nameof(model.SomeProperty), $"Whoops!!!");
}
}
}
然后您可以对
DemoViewModelValidator
心满意足!希望有人会发现这很有用!