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

2023-12-28

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

现在,视图模型有两个我希望从该方法内部访问的字段,以便可以使用“data-val”属性来呈现它们。我的问题是,我怎样才能得到一个名为“Myprop”的属性context这里?当我调试时,我可以在 context.ActionContext.ViewData.Model 下查看信息,但是当我使用 Visual Studio“快速监视”功能时,在调试期间我无法获取该信息。自定义属性位于视图模型上的属性上。

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,而不是使用属性,并覆盖添加验证属性 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>();
}

缺点是,如果你有多个模型,你需要这样做,它会很快变得非常难看。如果有人找到更好的方法,我很想听听:-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在AddValidation方法中访问模型数据asp.net core自定义验证 的相关文章

  • 用 C++ 进行服装建模 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在编写一些软件 最终会绘制一个人体框架 可以配置各种参数 并且计划是在假人身上放置某种衣服 我研究
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub
  • CSS3 背景渐变未验证,有人可以告诉我为什么吗?里面的代码示例

    有人能告诉我为什么下面的 css 没有验证吗 我一直在尝试自己研究这个问题 但没有运气 我读过的所有文档都说这是在 css3 中进行渐变的正确原因 header color white font size 12px font family

随机推荐