Проверки не завершаются в .Net Core 2.1 MVC, когда «требуемые» ключи JSON опущены - PullRequest
0 голосов
/ 09 октября 2018

Я новичок в разработке .Net, поэтому я решил начать с курса .Net Core.Все идет нормально;Я пытаюсь создать API, который требует наличия определенных ключей в объекте JSON.Если хотя бы один из ключей отсутствует, я ожидаю, что он будет недействительным.

[HttpPost("new")]
public IActionResult CreateGPSPoint([FromBody] ModelExample dataObject)
{
   if (!ModelState.IsValid)
   {
       return BadRequest(ModelState);
   }
}

IsValid возвращает true, однако, даже если я опускаю некоторые или все ключи в полезной нагрузке JSON, которыеЯ отправляю.При проверке те ключи, которые отсутствовали, устанавливаются в 0 в свойствах последующей модели;так вот как выглядит моя модель.

public class ModelExample
{
    [Required(AllowEmptyStrings = false)]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public float Height{ get; set; }

    [Required(AllowEmptyStrings = false)]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public decimal Width{ get; set; }

    [Required(AllowEmptyStrings = false)]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public int Depth{ get; set; }


    //Populated by the entity later, but feel free to critique nevertheless
    public int Id { get; set; }
}

Обратите внимание, что, поскольку этот вопрос поднимался несколько раз в другом месте, я попробовал различные комбинации Required (AllowEmptyStrings = false) и DisplayFormat (ConvertEmptyStringToNull = false) - я предполагал, что они будут проверены, когда объект JSON будет «преобразован (?)» В модель;однако результат всегда был одинаковым.

Изначально я думал, что это может быть проблема с Automapper (который я использую), но проверки проходят до того, как произойдет любое сопоставление сущности / модели.

Те конкретные поля, которые я пропустил, также никогда не могут быть нулевыми, поскольку никакое значение не будет установлено равным 0 (и в любом случае нулевое значение все равно будет действительным).

Я думал, чтопросто интерпретируйте данные как объект JSON (вместо ModelExample) и убедитесь, что эти ключи уже существуют в моей логике контроллера (что-то вроде Rails 'dataObject & .dig [: key] "- но я не знаю, так ли этовозможно или уместно, или если есть какая-то тактика .Net, которую я пропустил.

Мой вопрос на самом деле: что-то делается неправильно или отсутствует в вышеприведенном?

МногиеЗаранее благодарим, если кто-нибудь может рассказать о том, как работает вышеперечисленное!

1 Ответ

0 голосов
/ 09 октября 2018

Когда свойства класса инициализируются, они получают значение по умолчанию .

Для ссылочных типов это NULL, а для структур значение может варьироваться.

float, decimal и int являются структурами и инициализируются до их эквивалента 0.

Например, public int Depth { get; set; } будет инициализирован до 0.

Вы отправляете объект JSON без этих свойств или с этими неопределенными свойствами, и они не устанавливаются, то есть всегда используется значение по умолчанию 0.

0 существует и, таким образом, удовлетворяетпроверка "required".

Чтобы исправить это, задайте типы свойств nullable .

например

[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public float? Height{ get; set; }

[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal? Width{ get; set; }

[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int? Depth{ get; set; }

Таким образом, когдасвойства не определены в JSON, тогда они получат значение NULL, а NULL не удовлетворяет «требуемой» проверке.

, например, public int? Depth { get; set; } будет инициализировано NULL.


Другой вариант - использование BindRequiredAttribute .

Указывает, что прoperty требуется для привязки модели.При применении к свойству система привязки модели требует значения для этого свойства.При применении к типу система привязки модели требует значений для всех свойств, которые этот тип определяет.

например,

[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public float Height{ get; set; }

[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal Width{ get; set; }

[BindRequired]
[Required(AllowEmptyStrings = false)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public int Depth{ get; set; }

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.1#notes-on-the-use-of-the-required-attribute

Атрибут BindRequired [...] полезен для обеспечения полноты данных формы.При применении к свойству система привязки модели требует значение этого свойства.

...