使用数据注释的有条件必需的属性

2023-11-26

我有一堂这样的课:

public class Document
{
   public int DocumentType{get;set;}

   [Required]
   public string Name{get;set;}

   [Required]
   public string Name2{get;set;}
}

现在如果我放一个[Required]上的数据注释Name and Name2属性,那么一切都好,如果Name or Name2为空,验证将抛出错误。

但我想要Name仅当以下情况时才需要字段DocumentType等于 1 和Name2仅当需要DocumentType等于 2 。

public class Document
{
   public int DocumentType{get;set;}

   [Required(Expression<Func<object, bool>>)]
   public string Name{get;set;}

   [Required(Expression<Func<object, bool>>)]
   public string Name2{get;set;}
}

但我知道我不能,这会导致错误。针对这个需求我该怎么办?


requiredIf 验证属性

我写了一个RequiredIfAttribute当不同的属性具有特定值(您需要的)或不同的属性具有特定值时,需要特定的属性值除了一个特定的值。

这是可能有帮助的代码:

/// <summary>
/// Provides conditional validation based on related property value.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class RequiredIfAttribute : ValidationAttribute
{
    #region Properties

    /// <summary>
    /// Gets or sets the other property name that will be used during validation.
    /// </summary>
    /// <value>
    /// The other property name.
    /// </value>
    public string OtherProperty { get; private set; }

    /// <summary>
    /// Gets or sets the display name of the other property.
    /// </summary>
    /// <value>
    /// The display name of the other property.
    /// </value>
    public string OtherPropertyDisplayName { get; set; }

    /// <summary>
    /// Gets or sets the other property value that will be relevant for validation.
    /// </summary>
    /// <value>
    /// The other property value.
    /// </value>
    public object OtherPropertyValue { get; private set; }

    /// <summary>
    /// Gets or sets a value indicating whether other property's value should match or differ from provided other property's value (default is <c>false</c>).
    /// </summary>
    /// <value>
    ///   <c>true</c> if other property's value validation should be inverted; otherwise, <c>false</c>.
    /// </value>
    /// <remarks>
    /// How this works
    /// - true: validated property is required when other property doesn't equal provided value
    /// - false: validated property is required when other property matches provided value
    /// </remarks>
    public bool IsInverted { get; set; }

    /// <summary>
    /// Gets a value that indicates whether the attribute requires validation context.
    /// </summary>
    /// <returns><c>true</c> if the attribute requires validation context; otherwise, <c>false</c>.</returns>
    public override bool RequiresValidationContext
    {
        get { return true; }
    }

    #endregion

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="RequiredIfAttribute"/> class.
    /// </summary>
    /// <param name="otherProperty">The other property.</param>
    /// <param name="otherPropertyValue">The other property value.</param>
    public RequiredIfAttribute(string otherProperty, object otherPropertyValue)
        : base("'{0}' is required because '{1}' has a value {3}'{2}'.")
    {
        this.OtherProperty = otherProperty;
        this.OtherPropertyValue = otherPropertyValue;
        this.IsInverted = false;
    }

    #endregion

    /// <summary>
    /// Applies formatting to an error message, based on the data field where the error occurred.
    /// </summary>
    /// <param name="name">The name to include in the formatted message.</param>
    /// <returns>
    /// An instance of the formatted error message.
    /// </returns>
    public override string FormatErrorMessage(string name)
    {
        return string.Format(
            CultureInfo.CurrentCulture,
            base.ErrorMessageString,
            name,
            this.OtherPropertyDisplayName ?? this.OtherProperty,
            this.OtherPropertyValue,
            this.IsInverted ? "other than " : "of ");
    }

    /// <summary>
    /// Validates the specified value with respect to the current validation attribute.
    /// </summary>
    /// <param name="value">The value to validate.</param>
    /// <param name="validationContext">The context information about the validation operation.</param>
    /// <returns>
    /// An instance of the <see cref="T:System.ComponentModel.DataAnnotations.ValidationResult" /> class.
    /// </returns>
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException("validationContext");
        }

        PropertyInfo otherProperty = validationContext.ObjectType.GetProperty(this.OtherProperty);
        if (otherProperty == null)
        {
            return new ValidationResult(
                string.Format(CultureInfo.CurrentCulture, "Could not find a property named '{0}'.", this.OtherProperty));
        }

        object otherValue = otherProperty.GetValue(validationContext.ObjectInstance);

        // check if this value is actually required and validate it
        if (!this.IsInverted && object.Equals(otherValue, this.OtherPropertyValue) ||
            this.IsInverted && !object.Equals(otherValue, this.OtherPropertyValue))
        {
            if (value == null)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }

            // additional check for strings so they're not empty
            string val = value as string;
            if (val != null && val.Trim().Length == 0)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }
        }

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

使用数据注释的有条件必需的属性 的相关文章

  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • 获取两个字符串之间的公共部分c# [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要的是获取两个单词之间的共同部分并获取差异 例子 场景1 word1 感言 word2 Test 将返回 公共部分Test 不同之
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它

随机推荐

  • WebMethod 返回 JSON 格式的值

    如何将Webmethod的值以JSON格式返回给客户端 我想返回两个静态 int 值 我是否需要使用这两个属性创建新对象并返回它 GetStatus 方法被频繁调用 我不喜欢每次只是为了 json 格式创建一个特殊对象的想法 WebMeth
  • 为什么绝对定位元素显示在静态元素之上?

    我知道绝对定位会破坏正常流程 但由于 HTML 中的顺序是先是绝对元素 然后是静态元素 所以我希望它也能反映在显示顺序中 absolute position absolute width 100px height 100px backgro
  • 为什么Apple推荐使用dispatch_once来实现ARC下的单例模式?

    在ARC下单例的共享实例访问器中使用dispatch once的确切原因是什么 MyClass sharedInstance Static local predicate must be initialized to 0 static My
  • 在 AVAudioEngine 中从网络传输数据,可能吗?

    我有一个使用的应用程序AVAudioEngine用于从本地文件系统播放文件AVAudioPlayerNodes and AVAudioFiles 这工作得很好 现在我想让我的设置也支持从互联网上的服务器流式传输 MP3 文件 到目前为止我尝
  • 为什么安装VS 2017后命令行csc无法编译C#7?

    我刚刚下载了 Visual Studio 2017 RC 这是几天前发布并支持 C 7 我可以使用 IDE 中的 C 7 功能 然而 这种行为似乎不适用于命令行 我正在从事一个项目 需要csc用于处理 C 7 及更高版本的可执行文件 但是
  • 当我在 Windows 上克隆带有符号链接的存储库时会发生什么?

    关于在 Windows 上添加符号链接的支持存在很多问题 但是 当我克隆时实际发生了什么带有符号链接的存储库在 Windows 上 Since 版本1 5 3本机 Git 客户端git clone and git init将探测目标文件系统
  • 当程序崩溃且没有异常时如何调试程序?

    我的一个程序定期崩溃 但我不知道为什么 我在调试模式下运行它 但没有弹出任何内容 程序突然退出了 我遇到过其他确实引发异常的错误 但不是这个 有什么神奇的方法可以抓住它吗 假设您是从 Visual Studio 中运行它 并且由于某种原因
  • ADB 无法识别 Samsung Gear Live 或 LG G 手表

    我正在尝试执行adb在 Windows 7 上的 Samsung Gear Live 手表上 我似乎没有找到设备驱动程序来让它被 ADB 识别 这是我已经拥有的 我已经在 Gear Live 中启用了 ADB 调试 我转到设备管理器并将 g
  • 如何使用 log4net 记录 Threadpool 线程的正确上下文?

    我正在尝试找到一种方法来从一堆线程中记录有用的上下文 问题是 许多代码是在通过线程池线程到达的事件上处理的 据我所知 因此它们的名称与任何上下文都没有关系 该问题可以通过以下代码来演示 class Program private stati
  • Haxe - 打印命令行参数

    使用 Haxe 编程语言 是否可以打印传递给应用程序的命令行参数 我正在尝试在 Haxe 中重写这个 Java 程序 它只是打印命令行参数 public class JavaExample public static void main S
  • 在没有身份的情况下使用 Bearer/Jwt 授权

    我正在使用 Asp 5 开发 Web API 并阅读了一些有关 Web API 的文档 意识到我需要 Bearer 授权 经过查找 没有发现任何未经授权使用的文档或样本Aspnet Identity 我有自己的会员资格 但我不想使用Iden
  • 实现命令模式

    我正在设计一个应用程序 我想使用命令模式用于撤消 重做目的 我对命令模式做了一些研究 但我唯一不明白的是 命令是否应该具有撤消和重做方法 或者我应该创建两个单独的命令 一个用于撤消 一个用于重做 并从主命令本身 命令对象本身应该实现撤消 重
  • 单击 Facebook Like 按钮后显示内容

    我有一个网页部分 我只希望人们在单击 Facebook Like 按钮后能够访问该部分 如何隐藏该特定区域 然后仅在有人单击 赞 按钮后才显示它 至于 Facebook Like 代码 如下所示
  • 了解 PHP &(与号、按位与)运算符

    我经常使用 var 1 在我的代码中 如果 var是奇数 如果是偶数则为 false 但 实际上有什么作用呢 是二进制的and 如果你有一个二进制值 并且你and与另一个二进制值 则结果将是按位and两者之中 一个例子 01101010 0
  • 如何检索原始函数的形式?

    至少目前 这对我来说是一个学习练习 所以实际功能或其复杂性不是问题 假设我编写一个函数 其参数列表包含一些输入变量和函数名称 以字符串形式传递 然后 该函数在内部计算一些变量 并 决定 如何将它们提供给我传入的函数名称 对于非原始函数 我可
  • Chrome 扩展:webRequest.onBeforeSendHeaders 行为奇怪

    我正在尝试向 Chrome 扩展程序中的某些 AJAX 请求添加 Referer HTTP 标头 您无法直接在 AJAX 请求中更改它 因此我尝试使用网络请求 API chrome webRequest onBeforeSendHeader
  • Laravel Mail::send() 发送到多个收件人或密件抄送地址

    我似乎无法成功发送至multiple使用 Laravel 时的地址Mail send 回调 但是当我只指定时 代码确实有效one接受者 我尝试过链接 for example emails array email protected emai
  • 无法在已停止的 SparkContext 上调用方法

    当我运行以下测试时 它会抛出 无法在已停止的 SparkContext 上调用方法 可能的问题是我使用TestSuiteBase和流 Spark 上下文 在行val gridEvalsRDD ssc sparkContext paralle
  • 使用 linq 删除列表中的重复项

    我有课Items with properties Id Name Code Price 名单Items填充有重复的项目 例如 1 Item1 IT00001 100 2 Item2 IT00002 200 3 Item3 IT00003 1
  • 使用数据注释的有条件必需的属性

    我有一堂这样的课 public class Document public int DocumentType get set Required public string Name get set Required public strin