Хобрук: Ваш путь к мастерству в программировании

FluentValidation проверяет значение Enum

У меня есть следующая модель:

public class ViewDataItem
{
    public string viewName { get; set; }
    public UpdateIndicator updateIndicator { get; set; }
}

Со следующим перечислением:

public enum UpdateIndicator
{
    Original,
    Update,
    Delete
}

И следующий валидатор:

public class ViewValidator : AbstractValidator<ViewDataItem>
{
    public ViewValidator()
    {
        RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified");
        RuleFor(x => x.updateIndicator).SetValidator(new UpdateIndicatorEnumValidator<UpdateIndicator>());
    }
}

public class UpdateIndicatorEnumValidator<T> : PropertyValidator
{
    public UpdateIndicatorEnumValidator() : base("Invalid update indicator") {}

    protected override bool IsValid(PropertyValidatorContext context)
    {
        UpdateIndicator enumVal = (UpdateIndicator)Enum.Parse(typeof(UpdateIndicator), context.PropertyValue.ToString());

        if (!Enum.IsDefined(typeof(UpdateIndicator), enumVal))
          return false;

        return true;
    }
}

Код находится в WebAPI, который получает данные через JSON, десериализует их в объект и затем проверяет, но по какой-то причине я могу отправлять все, что захочу, в updateIndicator, пока я не ввожу целочисленное значение больше, чем max в перечислении (т.е. 1,2 или 3 работают нормально, но 7 вызовет ошибку).

Как я могу получить это, чтобы проверить ввод данных, которые я получаю, чтобы увидеть, действительно ли это значение находится в Enum?


  • Вы пытаетесь увидеть, является ли viewName текстовым значением в пределах UpdateIndicator? 10.07.2017
  • Я пытаюсь увидеть, действительно ли текстовое значение, отправленное как updateIndicator, существует в Enum UpdateIndicator. То есть, если кто-то отправляет бананы, он должен вернуть ошибку, но если кто-то отправляет оригинал (который существует в перечислении), он должен пройти проверку правильно. 10.07.2017
  • Этого не произойдет. Попробуйте вызвать конечную точку из Postman или Fiddler с недопустимым значением и посмотрите, что произойдет. Это даст вам значение перечисления по умолчанию (первое значение). Если вы хотите защититься от этого, вы можете сделать свойство обнуляемым, но ваша проверка не допускает пустых значений. 10.07.2017
  • Спасибо. Ты только что помог мне взорвать коробку. Это исправлено с нулевым Enum и проверкой нулевых значений. :) 10.07.2017
  • Я напишу ответ для этого тогда. Я уверен, что это пригодится кому-то в будущем. 10.07.2017

Ответы:


1

Проблема возникает из-за того, что построитель модели API преобразует то, что отправляется в перечисление. Если значение не найдено, оно не заполняется, и используется значение по умолчанию (как и для любого другого незаполненного типа данных свойства).

Чтобы легко определить, является ли отправленное значение допустимым значением перечисления, вы должны сделать свое свойство обнуляемым. Таким образом, если значение невозможно проанализировать, оно будет установлено на null. Если вы хотите убедиться, что свойство установлено, просто сделайте так, чтобы ваш валидатор не разрешал для него нулевые значения.

public class ViewDataItem
{
    public string viewName { get; set; }
    public UpdateIndicator? updateIndicator { get; set; }
}

public class ViewValidator : AbstractValidator<ViewDataItem>
{
    public ViewValidator()
    {
        RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified");
        RuleFor(x => x.updateIndicator).NotNull();
    }
}

Если для свойства не установлено значение null, ваша модель всегда будет иметь допустимое значение, когда оно у вас есть. В качестве альтернативы вы можете сделать первое значение вашего перечисления фиктивным значением, но это будет запах кода. Свойство нулевой модели имеет гораздо больше смысла.

Если вы хотите узнать, какое фактическое значение было отправлено в конечную точку API, вам нужно посмотреть на создание Обработчик HTTP, который выходит за рамки этого вопроса.

10.07.2017
  • Ответ Stacked - правильный способ сделать это. Хорошо убедиться, что значения находятся в пределах диапазона Enum. 29.10.2018

  • 2

    Попробуйте встроенный IsInEnum()

    RuleFor(x => x.updateIndicator).IsInEnum();
    

    Это проверяет, находится ли предоставленное значение перечисления в диапазоне вашего перечисления, если нет, проверка завершится ошибкой:

    «'updateIndicator' имеет диапазон значений, который не включает '7'».

    01.11.2017
  • Возможно, лучше проверить значение по умолчанию zero вручную. или добавьте NotNull() тоже. 08.10.2018
  • Новые материалы

    ВЫ РЕГРЕСС ЭТО?
    Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

    Расистский и сексистский робот, обученный в Интернете
    Его ИИ основан на предвзятых данных, которые создают предрассудки. Он словно переходит из одного эпизода в другой из серии Черное зеркало , а вместо этого представляет собой хронику..

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..