gpt4 book ai didi

c# - 在 AddValidation 方法中访问模型数据 asp.net core 自定义验证

转载 作者:行者123 更新时间:2023-11-30 12:08:54 24 4
gpt4 key购买 nike

我正在关注这个例子:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation并尝试实现我自己的自定义属性以进行验证。

现在,viewmodel 有两个字段,我希望从该方法内部访问它们,以便可以使用“data-val”属性呈现它们。我的问题是,如何从此处的 context 中获取名为“Myprop”的属性?当我调试时,我可以在 context.ActionContext.ViewData.Model 下查看信息,但是当我使用 Visual Studio“快速观察”功能时,我无法在调试期间获取该信息。自定义属性位于 View 模型的属性上。

public void AddValidation(ClientModelValidationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());

var year = _year.ToString(CultureInfo.InvariantCulture);
MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
}

最佳答案

我遇到了类似的问题。简短的回答是您不能从那里。您只能从那里访问元数据,而不能访问实际模型。这样做的原因是您的模型元数据和基于它的验证是在第一次使用时完成的,然后被缓存。因此,您永远无法通过属性装饰器更改基于模型返回的验证规则。

如果您需要根据模型的实例/内容动态决定要呈现哪些客户端data-val-* 属性,您需要继承DefaultValidationHtmlAttributeProvider,而不是使用属性,并覆盖 AddValidationAttributes方法。到目前为止,这是我发现的唯一方法。这是因为在此方法内部,您可以访问 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);
}
}
}

然后在Startup

ConfigureServices()中注册这个类
public void ConfigureServices(IServiceCollection services)
{
//All your other DI stuff here

//register the new ValidationHtmlAttributeProvider
services.AddSingleton<ValidationHtmlAttributeProvider, PseudoAttributeValidationHtmlAttributeProvider>();
}

缺点是,如果您有多个模型需要执行此操作,它会很快变得非常难看。如果有人找到了更好的方法,我很想听听 :-)

关于c# - 在 AddValidation 方法中访问模型数据 asp.net core 自定义验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45939333/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com