c# - 如何防止模型属性在 AspNet Core 的 mvc 控制器中被验证?
问题描述
我有一个 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 正在为列表中的每个员工调用验证,如果有任何被拒绝的员工,则将 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)
{
...
}
解决方案
以下可能是我的最终解决方案。
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; }
}
推荐阅读
- windows-mixed-reality - 在 HMD 上显示之前修改渲染帧(即过滤器)?
- android - 根据状态更改按钮背景颜色 - ColorStateList
- javascript - 在功能组件中更改列表项焦点颜色 onClick
- javascript - 如何在多维数组中循环以使用扩展运算符捕获最后一个节点
- python - 车辆路线问题 - 如何完成/确定何时访问某些位置?
- android - 无法使用 jetpack Compose 获得测试结果,(始终显示为已取消)
- javascript - 在javascript中映射大型数组而不会导致浏览器崩溃
- android - Firebase Recycler Paging Adapter 复制最后一项
- python - 使用 NLTK postag 后将字符串从列表附加到数组
- spring-cloud-gateway - Zuul 无法对具有不同端口的同一生产者进行负载均衡