.net 如何在模型验证中验证非法字段

.net 如何在模型验证中验证非法字段,.net,asp.net-core-webapi,core,.net,Asp.net Core Webapi,Core,我有一个.NETCore2.2WebAPI,它接受PersonDto,它通过模型验证得到验证,但它不检查非法字段。它只检查匹配字段是否有效 我希望确保提供的JSON只包含Dto(类)中的字段 我的控制器简化如下: public async Task<ActionResult<Person>> Post([FromBody] PersonDto personDto) { // do things } 我希望模型验证会抱怨“Name”字段不存在 如何检查非法字段?

我有一个.NETCore2.2WebAPI,它接受PersonDto,它通过模型验证得到验证,但它不检查非法字段。它只检查匹配字段是否有效

我希望确保提供的JSON只包含Dto(类)中的字段

我的控制器简化如下:

public async  Task<ActionResult<Person>> Post([FromBody] PersonDto personDto)
{
    // do things
}
我希望模型验证会抱怨“Name”字段不存在


如何检查非法字段?

您可以使用
ActionFilter
Reflection
将请求正文内容与模型字段进行比较。如果存在意外字段,请手动添加模型错误,并且
ModelState.IsValid
将为false

1.创建ActionFilter

public class CompareFieldsActionFilter : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext context)
    { 
        //get all fields name
        var listOfFieldNames = typeof(PersonDto).GetProperties().Select(f => f.Name).ToList();

        var request = context.HttpContext.Request;
        request.Body.Position = 0;

        using (var reader = new StreamReader(request.Body))
        {
            //get request body content
            var bodyString = reader.ReadToEnd();                

            //transfer content to json
            JObject json = JObject.Parse(bodyString);

            //if json contains fields that do not exist in Model, add model error                
            foreach (JProperty property in json.Children())
            {
                if (!listOfFieldNames.Contains(property.Name))
                {
                    context.ModelState.AddModelError("Filed", "Field does not exist");                      
                }
            }
        }
        base.OnActionExecuting(context);
    }
}
2.在您的操作中使用过滤器:

[HttpPost]
[CompareFieldsActionFilter]
public async  Task<ActionResult<Person>> Post([FromBody] PersonDto personDto)
{
   if (ModelState.IsValid)
    {
       // do things
    }
  // do things
}
[HttpPost]
[CompareFieldsActionFilter]
公共异步任务发布([FromBody]PersonDto PersonDto)
{
if(ModelState.IsValid)
{
//做事
}
//做事
}

为什么要检查未知字段,为什么不能忽略它们?为了防止调用客户端出错。您应该使用ModelState来检查非法字段?你看到邢的答案了吗?它将非法字段添加到modelstate错误集合中。有更好的方法吗?正如我之前所说的,没有必要保护客户犯错误。假设您有一个需要名称和年龄的模型,如果您传递了这些值和高度ModelState.IsValid返回true并忽略高度。但如果只传递name和height ModelState.IsValid,则返回false。所以我不明白你为什么要做一个额外的过滤器。你唯一增加的是额外的共谋和降低性能。就我的20美分。
public class CompareFieldsActionFilter : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext context)
    { 
        //get all fields name
        var listOfFieldNames = typeof(PersonDto).GetProperties().Select(f => f.Name).ToList();

        var request = context.HttpContext.Request;
        request.Body.Position = 0;

        using (var reader = new StreamReader(request.Body))
        {
            //get request body content
            var bodyString = reader.ReadToEnd();                

            //transfer content to json
            JObject json = JObject.Parse(bodyString);

            //if json contains fields that do not exist in Model, add model error                
            foreach (JProperty property in json.Children())
            {
                if (!listOfFieldNames.Contains(property.Name))
                {
                    context.ModelState.AddModelError("Filed", "Field does not exist");                      
                }
            }
        }
        base.OnActionExecuting(context);
    }
}
[HttpPost]
[CompareFieldsActionFilter]
public async  Task<ActionResult<Person>> Post([FromBody] PersonDto personDto)
{
   if (ModelState.IsValid)
    {
       // do things
    }
  // do things
}