从对象验证器访问完整的json

时间:2017-02-22 18:58:35

标签: validation .net-core asp.net-core-webapi

我的网络API公开以下方法

[HttpPost]
public IActionResult MyPostMethod([FromBody]Company company)
{
   .......
}

公司类如下所示

public class Company
    {
        public Guid CompanyGuid { get; set; }
        public string Name { get; set; }
        public List<Employee> Employees { get; set; }
    }


[EmployeeValidation]
public class Employee
    {
        public Guid EmployeeGuid { get; set; }
        public string Name { get; set; }
    }

正如您所看到的,Employee类使用如下实现的验证属性进行修饰。

public class EmployeeValidationAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var logger = (ILogger<EmployeeValidationAttribute>)validationContext.GetService(typeof(ILogger<EmployeeValidationAttribute>));
            List<Employee> Employees = (List<Employee>)validationContext.ObjectInstance;

            foreach (Employee Employee in Employees)
            {
                if (Employee.EmployeeGuid == Guid.Empty)
                {
                    return new ValidationResult("Invalid Employee Guid");
                }
            }
            return ValidationResult.Success;
        }
    }

让我们说当Employee对象验证出现问题时,我想将整个JSON输入记录到MyPostMethod方法。但是在验证程序中,我只能访问 Employee 对象。无论如何,我可以在员工对象的验证器中访问公司的JSON输入吗?

1 个答案:

答案 0 :(得分:1)

validationContext对公司实例一无所知。

您需要构建公司验证属性,而不仅仅是员工。

[CompanyValidation]
public class Company
{
    public String CompanyGuid { get; set; }
    public string Name { get; set; }
    public List<Employee> Employees { get; set; }
}

public class CompanyValidationAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var logger = (ILogger<CompanyValidationAttribute>)validationContext.GetService(typeof(ILogger<CompanyValidationAttribute>));
        var company = (Company)validationContext.ObjectInstance;

        // don't forget to check for null
        foreach (Employee Employee in company.Employees)
        {
            if (Employee.EmployeeGuid == Guid.Empty)
            {
                return new ValidationResult("Invalid Employee Guid");
            }
        }
        return ValidationResult.Success;
    }
}

另一种方法

此处,value参数只是所讨论的单个属性,但validationContext.ObjectInstance成为容器对象,即公司。

public class MyController : Controller
{
    [HttpPost]
    public object Post([FromBody]Company company)
    {
        if (!ModelState.IsValid)
        {
            //log here
        }

        return true;
    }
}

public class Company
{
    [GuidValidation]
    public Guid CompanyGuid { get; set; }
    public String Name { get; set; }
    public List<Employee> Employees { get; set; }
}

public class Employee
{
    [GuidValidation]
    public Guid EmployeeGuid { get; set; }
    public String Name { get; set; }
}

public class GuidValidationAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null && validationContext.ObjectInstance != null)
        {
            var model = (Guid)value;

            if (model == Guid.Empty)
            {
                return new ValidationResult("Guid cannot be empty.");
            }
        }

        return ValidationResult.Success;
    }
}