2017-02-22 33 views
0

我的Web API暴露下面的方法充分利用对象验证访问完整的JSON

[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方法。但是在验证器中,我只能访问员工对象。有反正我能得到验证中获得JSON输入为公司员工对象?

回答

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; 
    } 
} 
+0

我想我的问题的重点是要知道如果它可能得到一个验证程序,我可以访问完整的JSON对象。我知道我可以为根对象创建一个验证器并验证所有包含的对象(就像您为公司验证器所建议的那样),但这正是我不想实现的目标。此外,当验证程序属性报告验证错误时,请求似乎不会对Post方法产生影响。 –

+0

@Jimcrown好吧,我明白了我没有找到一个类级别的验证属性给你的容器对象,而是一个属性级的验证属性会,不知道为什么......如果后期不绑定到您的行动的参数,那么你将不得不查看asp.net mvc模型绑定功能的命名约定。 –