You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Owned类Address的属性设置条件性必填规则

实现Address类的条件性必填验证逻辑

针对你的需求——同一个Address类在Application的不同属性下有不同的必填规则(CorpOffice必填Street/City/State/Zip,Offsite_Facility全可选),可以通过以下两种方式实现,确保Validator.TryValidateObject能捕获缺失的必填属性错误:


方案1:让Application实现IValidatableObject接口

直接在Application类的验证方法中,针对CorpOffice单独做必填字段校验,Offsite_Facility不做强制要求。

修改后的代码

Address类保持原有结构不变,修改Application类:

using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

public class Application : IValidatableObject
{
    [Required(ErrorMessage = "公司办公地址不能为空")]
    public Address CorpOffice { get; set; }

    public Address Offsite_Facility { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // 校验CorpOffice的必填字段
        if (CorpOffice != null)
        {
            if (string.IsNullOrWhiteSpace(CorpOffice.Street))
            {
                yield return new ValidationResult(
                    "公司办公地址的街道不能为空",
                    new[] { $"{nameof(CorpOffice)}.{nameof(CorpOffice.Street)}" });
            }

            if (string.IsNullOrWhiteSpace(CorpOffice.City))
            {
                yield return new ValidationResult(
                    "公司办公地址的城市不能为空",
                    new[] { $"{nameof(CorpOffice)}.{nameof(CorpOffice.City)}" });
            }

            if (CorpOffice.State == null)
            {
                yield return new ValidationResult(
                    "公司办公地址的州/省份不能为空",
                    new[] { $"{nameof(CorpOffice)}.{nameof(CorpOffice.State)}" });
            }

            if (!CorpOffice.Zip.HasValue)
            {
                yield return new ValidationResult(
                    "公司办公地址的邮编不能为空",
                    new[] { $"{nameof(CorpOffice)}.{nameof(CorpOffice.Zip)}" });
            }
        }

        // Offsite_Facility 无需强制校验,跳过即可
    }
}

验证调用示例

// 构造一个CorpOffice缺失必填字段的Application实例
var app = new Application
{
    CorpOffice = new Address() // 仅实例化,未填充必填字段
    // Offsite_Facility 可以不赋值
};

var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(
    app,
    new ValidationContext(app),
    validationResults,
    validateAllProperties: true); // 必须设为true,否则不会触发自定义校验

// 输出所有验证错误
foreach (var result in validationResults)
{
    Console.WriteLine($"错误:{result.ErrorMessage},关联字段:{string.Join(", ", result.MemberNames)}");
}

方案2:自定义验证属性

创建一个可复用的RequiredAddressAttribute,标记在需要强制校验的Address属性上(比如CorpOffice),这种方式更灵活,适合多个地方复用同一规则。

自定义验证属性代码

using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

public class RequiredAddressAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var address = value as Address;
        if (address == null)
        {
            return new ValidationResult("地址不能为空");
        }

        var errorMessages = new List<string>();
        if (string.IsNullOrWhiteSpace(address.Street)) errorMessages.Add("街道不能为空");
        if (string.IsNullOrWhiteSpace(address.City)) errorMessages.Add("城市不能为空");
        if (address.State == null) errorMessages.Add("州/省份不能为空");
        if (!address.Zip.HasValue) errorMessages.Add("邮编不能为空");

        if (errorMessages.Any())
        {
            return new ValidationResult(
                $"地址信息不完整:{string.Join(";", errorMessages)}",
                new[] { validationContext.MemberName });
        }

        return ValidationResult.Success;
    }
}

修改Application类

public class Application
{
    [RequiredAddress(ErrorMessage = "公司办公地址信息不完整")]
    public Address CorpOffice { get; set; }

    public Address Offsite_Facility { get; set; }
}

验证调用和方案1完全一致,同样能捕获CorpOffice的必填字段缺失错误。


关键注意点

调用Validator.TryValidateObject时,必须设置validateAllProperties: true,否则只会校验顶级的[Required]属性,不会触发自定义验证或IValidatableObject的逻辑。

如果需要实现“Offsite_Facility若赋值则必须填全”的逻辑,只需在方案1的Validate方法中添加判断:当Offsite_Facility不为空时,执行和CorpOffice一样的字段校验即可。

内容的提问来源于stack exchange,提问作者Red_Phoenix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:33:17