Как проверить наличие недопустимых полей в Проверке модели - PullRequest
0 голосов
/ 04 июня 2019

У меня есть веб-API .NET Core 2.2, который принимает PersonDto, он проверяется с помощью проверки модели, но не проверяет наличие недопустимых полей.Он только проверяет допустимость соответствующих полей.

Я хочу убедиться, что поставляемый JSON содержит только те поля, которые есть в моем Dto (классе).

public class PersonDto
  {
    public string firstname { get; set; }
    public string lastname { get; set; }
  }

Мой контроллер выглядит так:

public async  Task<ActionResult<Person>> Post([FromBody] PersonDto personDto)
{
    // do things
}

Я отправляю неправильные поля (имя не существует в моем dto), и ModelState действителен.

{
  "name": "Diego"
}

Я ожидал, что Проверка модели пожалуется на то, что поле "Имя" не существует.

Как я могу проверить наличие незаконных полей?

1 Ответ

0 голосов
/ 05 июня 2019

Вы можете использовать ActionFilter и Reflection для сравнения содержимого тела запроса с полями модели. Если есть неожиданные поля, добавьте ошибки модели вручную, и ModelState.IsValid будет иметь значение false.

1.Создать фильтр действий

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
}
...