2017-02-22 39 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模型綁定功能的命名約定。 –