我遇到了类似的问题。简短的回答是你不能从那里。您只能从那里访问元数据,而不能访问实际模型。原因是您的模型元数据和基于它的验证是在第一次使用时完成的,然后进行缓存。因此,您永远无法通过属性装饰器更改基于模型返回的验证规则。
如果您需要动态决定哪个客户端data-val-*
渲染的属性基于实例/内容你的模型,你需要继承DefaultValidationHtmlAttributeProvider
,而不是使用属性,并覆盖添加验证属性 https://github.com/aspnet/Mvc/blob/cfc05104e416f253bdfc07603f3e387c77aea975/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/DefaultValidationHtmlAttributeProvider.cs#L58方法。这是迄今为止我发现的唯一方法。这是因为在此方法内部,您可以访问ModelExplorer
public class CustomValidationHtmlAttributeProvider : DefaultValidationHtmlAttributeProvider
{
private readonly IModelMetadataProvider metadataProvider;
public CustomValidationHtmlAttributeProvider(IOptions<MvcViewOptions> optionsAccessor, IModelMetadataProvider metadataProvider, ClientValidatorCache clientValidatorCache)
: base(optionsAccessor, metadataProvider, clientValidatorCache)
{
this.metadataProvider = metadataProvider;
}
public override void AddValidationAttributes(ViewContext viewContext, ModelExplorer modelExplorer, IDictionary<string, string> attributes)
{
//base implimentation
base.AddValidationAttributes(viewContext, modelExplorer, attributes);
//re-create the validation context (since it's encapsulated inside of the base implimentation)
var context = new ClientModelValidationContext(viewContext, modelExplorer.Metadata, metadataProvider, attributes);
//Only proceed if it's the model you need to do custom logic for
if (!(modelExplorer.Container.Model is MyViewModelClass model) || !modelExplorer.Metadata.PropertyName == "Myprop") return;
//Do stuff!
var validationAttributeAdapterProvider = viewContext.HttpContext.RequestServices.GetRequiredService<IValidationAttributeAdapterProvider>();
if (model.Myprop)
{
var validationAdapter = (RequiredAttributeAdapter)validationAttributeAdapterProvider.GetAttributeAdapter(new RequiredAttribute(), null);
validationAdapter.Attribute.ErrorMessage = "You not enter right stuff!";
validationAdapter.AddValidation(context);
}
}
}
然后将这个类注册到ConfigureServices()
你的Startup
public void ConfigureServices(IServiceCollection services)
{
//All your other DI stuff here
//register the new ValidationHtmlAttributeProvider
services.AddSingleton<ValidationHtmlAttributeProvider, PseudoAttributeValidationHtmlAttributeProvider>();
}
缺点是,如果你有多个模型,你需要这样做,它会很快变得非常难看。如果有人找到更好的方法,我很想听听:-)