我有一个MVC控制器操作,它接收带有一些员工列表的复杂类型。在我的自定义模型绑定器中,我将员工分为已接受和拒绝,并返回ExcelEmployeeModel
public class ExcelEmployeeModel
{
[Required] public String Description { get; set; }
public List<Employee> Accepted { get; set; }
public List<Employee> RejectedEmployees { get; set; }
}
public class Employee
{
public Int32 Id { get; set; }
[Required] public string FirstName { get; set; }
[Required] public string LastName { get; set; }
}
似乎AspNetCore正在为列表中的每个员工调用validate,如果有任何被拒绝的员工,则将BadRequest对象发送回客户端。因此,如果有任何被拒绝的员工,则永远不会执行该操作。
如何防止RejectedEmployees等属性被验证?
能够使用自定义属性装饰我的属性会很好,如下所示:
[NoValidation]
public List<Employee> RejectedEmployees {get;set;}
此ValidationAttribute是验证员工项目并从那里返回错误请求的原因。
// Conifguration file StartUp.cs
services.AddMvc(options =>
{
options.Filters.Add(new ValidateModelAttribute());
}
// Custom validation attribute class
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
这是应该接收数据的动作,但事实并非如此。
[HttpPost]
public async Task<IActionResult> Post([FromBody] ExcelEmployeeModel model)
{
...
}
答案 0 :(得分:0)
以下可能是我的最终解决方案。
public class NoValidationAttribute : ValidationAttribute
{
public static void RemoveValidation(ActionExecutingContext context)
{
// Get the properties that contain the [NoValidationAttribute]
var properties = context.ActionArguments.First().Value.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(a =>
a.GetCustomAttributes(true).OfType<NoValidationAttribute>().Any());
// For each of the properties remove the modelstate errors.
foreach (var property in properties)
{
foreach (var key in context.ModelState.Keys.Where(k =>
k.StartsWith($"{property.Name}["))) // Item index is part of key [
{
context.ModelState.Remove(key);
}
}
}
}
我的ValidationModelAttribute现在如下:
public override void OnActionExecuting(ActionExecutingContext context)
{
NoValidationAttribute.RemoveValidation(context);
// Finally validation passes for properties using the [NoValidateAttribute]
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
// Model using the NoValidationAttribute
public class ExcelEmployeeModel
{
[Required] public String Description { get; set; }
public List<Employee> Accepted { get; set; }
[NoValidation]
public List<Employee> RejectedEmployees { get; set; }
}