Специальная проверка веб-API для проверки строки по списку утвержденных значений

Я хотел бы проверить ввод данных в команде REST Web API. Я хотел бы, чтобы он работал над чем-то вроде State ниже, украшенным атрибутом, который ограничивает допустимые значения параметра.

public class Item {
    ...

    // I want State to only be one of "New", "Used", or "Unknown"
    [Required]
    [ValidValues({"New", "Used", "Unknown"})]
    public string State { get; set; }

    [Required]
    public string Description { get; set; }

    ...
}

Есть ли способ сделать это, не противоречая текстуре Web API. В идеале этот подход будет похож на пользовательскую проверку правильности Ruby on Rails .

Ответ 1

Создайте собственный атрибут проверки, полученный из ValidationAttribute и переопределите функцию члена IsValid.

public class ValidValuesAttribute: ValidationAttribute
{
  string[] _args;

  public ValidValuesAttribute(params string[] args)
  {
    _args = args;
  }

  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if (_args.Contains((string)value))
      return ValidationResult.Success;
    return new ValidationResult("Invalid value.");
  }
}

Затем вы можете сделать

[ValidValues("New", "Used", "Unknown")]

Вышеприведенный код не был скомпилирован или протестирован.

Ответ 2

Как передается значение API? Это параметр запроса или он находится в теле? Обычно я просто делал чек на уровне обработчика запросов. Если вы поместите принятые значения в список или массив, вы можете просто использовать метод расширения Contains.

  if (validStates.Contains(input))
  {
     return MethodThatProcessesRequest(requiredData);
  }
  else
  {
     return ErrorHandlingMethod(requiredData);
  }

Этот тип проверки должен выполняться на стороне сервера. Не стесняйтесь ограничивать ввод в пользовательском интерфейсе, но если вы создаете REST API, он должен проверять все входные данные независимо от того, что делает ваш клиент.

Ответ 3

Внедрите объект IValidatableObject для элемента, который потребует, чтобы вы реализовали метод Validate, а затем в Validate запишите свое условие, чтобы проверить, действительно ли оно:

public IEnumerable<ValidationResult> Validate(ValidationContext context) {
    if (!States.contains(this.State)){
        yield return new ValidationResult("Invalid state.", new[] { "State" });
    }
}