如何在 api 模型验证过程 asp.net c# 中获取父属性名称?

问题描述

我有一个类模型如下:

public class QuataShareSurplussFormModel
{

    public QuataShareSurplussOfferLetterModel offeredLetters { get; set; }
    [ListValidations]
    [ListDuplicateValidations]
    public List<QuataShareClassModel> quataShareClass { get; set; }
    [ListValidations]
    [ListDuplicateValidations]
    public List<SurplusClassModel> surplusClass { get; set; }
    [ListDuplicateValidations]
    public List<OfferedLettersClauseModel> lettersClauses { get; set; }
    [ListDuplicateValidations]
    public List<OfferedLettersExclusionsModel> lettersExclusions { get; set; }
    [ListDuplicateValidations]
    public List<OfferedLettersGeneralConditionsModel> lettersGeneralConditions { get; set; }
    [ListDuplicateValidations]
    public List<OfferedLetteRSSpecialConditionsModel> letteRSSpecialConditions { get; set; }
    [ListDuplicateValidations]
    public List<OfferedLettersGeneralExclusionsModel> lettersGeneralExclusions { get; set; }

}

quataShareClass 属性具有以下项目:

public class QuataShareClassModel
{
    public int offeredLetterId { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(1,int.MaxValue)]
    public int? classId { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(0,long.MaxValue)]
    public long? maxLimitOfCover { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(0,byte.MaxValue)]
    public byte? baseDataServiceCurrencyTypeId { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(0,int.MaxValue)]
    public Nullable<int> exchangeRate { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(0,long.MaxValue)]
    [CalculativeIRRCheck(nameof(maxLimitOfCover),nameof(exchangeRate))]
    public long? maxLimitOfCoverInIRR { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(0,byte.MaxValue)]
    public long? commission { get; set; }
    [ProprequiredValidation]
    [PropRangeValidation(1,int.MaxValue)]
    public int? lastLossRatio { get; set; }
}

例如,假设我想验证 commission 属性

public class PropRangeValidation : RangeAttribute
{
    private readonly double _Minimum;
    private readonly double _Maximum;

    public PropRangeValidation(double minimum,double maximum) : base( minimum,maximum)
    {
        this._Minimum = minimum;
        this._Maximum = maximum;
    }
    protected override ValidationResult IsValid(object value,ValidationContext validationContext)
    {
        var valueStr = value?.ToString();
        var valueDbl = Convert.Todouble(valueStr);

        if ((valueDbl < _Minimum || valueDbl > _Maximum) && valueStr!=null)
        {
            var memberName = validationContext.MemberName;
            var errorMsg = string.Format(Resources.RangeViolation,valueDbl,memberName);
            var errorCode = ValidationError.required.ToString();
            var error = string.Format("{0}|{1}|{2}",errorMsg,errorCode,memberName);
            return new ValidationResult(error);
        }
        return null;


    }
}

如何从 commission 获取 ValidationContext属性名称?我是说

public List<QuataShareClassModel> quataShareClass { get; set; }

我需要获得 quataShareClass 的名字。

像这样:

var parentProp=ValidationContext.ParentProperty //results to `quataShareClass`

解决方法

我建议您实现 IValidatableObject 接口。它确定指定的对象是否有效。有一个 Validate 方法返回 ValidationResult 的集合,因此您可以使用 yield return 来获取结果。您不需要调用 Validate 方法,它由 .net 管理。

public class QuataShareClassModel : IValidatableObject
{
    public int offeredLetterId { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(1,int.MaxValue)]
    public int? classId { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(0,long.MaxValue)]
    public long? maxLimitOfCover { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(0,byte.MaxValue)]
    public byte? baseDataServiceCurrencyTypeId { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(0,int.MaxValue)]
    public Nullable<int> exchangeRate { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(0,long.MaxValue)]
    [CalculativeIRRCheck(nameof(maxLimitOfCover),nameof(exchangeRate))]
    public long? maxLimitOfCoverInIRR { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(0,byte.MaxValue)]
    public long? commission { get; set; }
    [PropRequiredValidation]
    [PropRangeValidation(1,int.MaxValue)]
    public int? lastLossRatio { get; set; }

    public QuataShareSurplussFormModel QuataShareSurplussFormModel { get; set; }
    
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (condition)
            yield return new ValidationResult("your message...",new[]
            {
                nameof([YourProperName])
            });

        if (condition)
            yield return new ValidationResult("your massage...",new[]
            {
                nameof(YourProperName1),nameof(YourProperName2)
            });
    }
}

看看IValidatableObject Interface

更新:

添加反向导航属性以访问QuataShareSurplussFormModel