Пользовательская проверка Asp.net-MVC - NULL против пустых

1

Для безопасности и согласованности я бы хотел проверить на пост-обратно, если поле отсутствует? В Java (например, сервлеты), когда мы выполняем request.getParameter(key) результатом является либо значение String, либо иначе NULL, если поле отсутствует. В MVC я создал пользовательскую проверку, которую я называю "ThrowOnNull". Поведение, которое я пытаюсь захватить, - это: Если нужного поля отсутствует (null), я хочу бросить, иначе вернем успех.

Рассмотрим этот пользовательский валидатор (который не работает):

public class ThrowOnNull: ValidationAttribute
{
   public ThrowOnNull() { }

   protected override ValidationResult IsValid(object value, ValidationContext validationContext)
   {            
       if (value == null)
           throw new Exception(validationContext.MemberName + " field expected, but missing."));            

       return ValidationResult.Success;
   }
}

Можно ли делать то, что я хочу здесь? (этот валидатор работает не так, как ожидалось, и потому, что структура присваивает NULL пустое значение [oh dear].)

ОБНОВЛЕНИЕ: В примере @emodendroket следующий пример кода теперь работает так, как ожидалось:

public class ThrowOnMissing: ValidationAttribute
{
    public ThrowOnMissing() { }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (!HttpContext.Current.Request.Form.AllKeys.Contains(validationContext.MemberName))
            throw new Exception(validationContext.MemberName + " field expected, but missing.");

        return ValidationResult.Success;
    }
}

EDIT: Я тщательно очистил код вопроса и примера, чтобы сделать его намного понятнее, надеюсь, что это поможет.

  • 0
    Я не понимаю, как ответ, который вы приняли, решает проблему, о которой вы так непреклонны ....
  • 0
    Короче говоря: это решает, потому что объясняет, как это возможно для того, что я хочу. Что такое: Проверьте необработанную входящую передачу на согласованность через пользовательский валидатор. Далее: обеспечение того, что мое приложение ожидает от входящих данных (полей). Если нет, киньте, войдите и перенаправьте. Этот метод рассматривает структуру (и любую зависимость от нее), просматривая необработанный поток, что позволяет мне проводить упреждающую (предварительную) проверку и сертификацию. Я приветствую подход MVC, если предложен или объяснен разумный (чего не было). В противном случае, я посмотрю на фреймворк и проверим его сам.
Теги:
validation
asp.net-mvc

4 ответа

2
Лучший ответ

Если вам нужен собственный валидатор, вы можете посмотреть словарь HttpContext.Current.Request.Form. Затем вы можете сделать то, что вы предложили с помощью этого кода:

if (!HttpContext.Current.Request.Form.AllKeys.Contains("prop"))
  {
    throw new Exception();
  }
  • 0
    Проблема в том, что вы не сможете выполнить этот код, пока связыватель модели не выполнит полную проверку. Таким образом, ваше требование прервать валидацию не удовлетворяется этим подходом.
  • 0
    @ErikFunkenbusch Ну, теперь, когда вы упомянули об этом, вы правы в этом, поскольку к тому времени, когда вы находитесь внутри своего действия, модель уже связана. Помещение этого внутрь пользовательского модельного переплета предположительно будет работать. Можно даже просто связать модель, наследуя ее от значения по умолчанию, и отразить все свойства с помощью атрибута, а затем выбросить, если какой-либо из их ключей отсутствует, а затем перейти к базовому методу.
Показать ещё 3 комментария
3

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

Вероятно, вам следует переопределить, что означает "недостающее значение".

РЕДАКТИРОВАТЬ:
После некоторого обсуждения кажется, что вас действительно не интересуют нулевые значения, а о безопасности (ложные формы с отсутствующими полями и тому подобное). В этом случае вы должны просто использовать стандартную марку antiforgery и, возможно, проверить происхождение запроса. Вы должны быть более чем прекрасным таким образом. Проверка недостающих полей не поможет, потому что злоумышленник может легко отправить эти поля.

Перегрузка/Под проводкой является реальной проблемой. Кроме того, если поля не отправлены (из-за какой-либо взлома или атаки DOS)

На самом деле, нет.

Overposting обрабатывается методом действия на контроллере. Он не будет принимать больше параметров, чем вы указали.

Underposting будет обрабатываться почти так же, как если бы вы не заполняли текстовые поля в форме, опять же без проблем, если вы правильно подтвердили свою модель.

DDOS-атака не может быть предотвращена, поверьте, некоторые проверки отсутствующих полей не помогут, если у кого-то есть сеть, достаточно мощная, чтобы вызвать DDOS. Просто просмотрите последние случаи при атаках, и вы поймете, что если ОГРОМНЫЕ серверы не могут этого выдержать, вы, конечно же, не сможете это предотвратить.

Ваша проверка данных также не должна быть слишком дорогостоящей. Это веб, люди не любят ждать слишком много.

  • 0
    Все поля, принадлежащие этой форме, не существуют, если кто-то (хакер) отправляет только подмножество полей. Смысл проверки состоит в том, чтобы фактически подтвердить, что ВСЕ ожидаемые поля действительно были возвращены. Это проверка безопасности, согласованности. Это предназначено, чтобы помешать / войти и сообщить о неожиданном поведении.
  • 0
    @JasonCaldwell, Обязательный атрибут будет достаточно в этом случае ..
Показать ещё 26 комментариев
1

Я думаю, вы здесь необоснованно параноичны. Заметьте, что я сказал, что необоснованно параноидально, так как небольшая паранойя - это хорошо.

Во-первых, давайте проанализируем "угрозы" и определим риски. Вы представили несколько аргументов:

  1. Чрезмерная проводка
  2. Под-проводок
  3. Проверка пустой vs null

Первый элемент не является проблемой в MVC, если вы используете View Model. Вы просто не можете публиковать информацию, которую вид не ожидает (ну, можно, но он игнорируется). Если вы не используете модель представления (или не используете правильно определенный), вы можете использовать атрибуты привязки, чтобы предотвратить публикацию элементов, которые вы не хотите связывать.

Второе, недопоставление, если это действительно является проблемой для вашей модели (99.999% времени, просто рассматривая ее по мере необходимости, более чем нормально, но нормально давайте рассмотрим ваш аргумент. Проблема здесь не в атрибуте проверки, это модель вам просто нужно зарегистрировать настраиваемое связующее устройство, которое ищет отсутствующие значения в вашей модели представления и выбрасывает, если они равны нулю. Это легко осуществить, отразив над связанной моделью и сравнив ее с опубликованными значениями, а затем выбросьте.

Проблема с вашим подходом RequiredThrowIfNull заключается в том, что, если это не требуется, и оно опубликовано? Это все еще ошибка в соответствии с вашими аргументами.

Наконец, проверка пустых vs null... вы говорите о дорогостоящей проверке... Я не знаю, какую дорогостоящую проверку вы могли бы здесь говорить, но на стороне сервера отмечается атрибуты, которые можно считать дорогостоящими.

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

.NET не является Java, хотя он в значительной степени работает аналогично... попытка повторной реализации шаблонов Java в.NET будет приводить к нищете с вашей стороны, потому что многие базовые философии просто разные.

Даже если мы примем ваш аргумент о желании поймать ошибки или быть уведомлены о попытках взлома, бросать в большинстве случаев неправильно. Вместо этого просто зарегистрируйте информацию из привязки модели и продолжайте работу в обычном режиме. Бросьте только, если вам абсолютно необходимо отменить запрос, и большую часть времени это просто не так, даже если вас взломали. Бросок просто заставит атакующего изменять свою атаку, пока они больше не получат исключение.

Честно говоря, это переработанное решение, которое ищет проблему, и есть много хороших.net конкретных способов решения проблем, которые вы пытаетесь решить.

  • 0
    Я в значительной степени не согласен. Здесь недостаточно места, чтобы взять вас по пунктам, но, как я сказал Вальтеру: «Существуют разные формы проверки. Есть проверка ввода пользователя и есть согласованность и проверка ошибок системы / данных. У каждого есть свое место. Согласованность гарантирует то, что приходит». то, что я ожидаю, - это то, чего я не ожидаю, и если это не так, то кто-то либо напортачил с моим сайтом, либо у меня где-то возникла ошибка. Такие ошибки не для конечных пользователей, и лучше всего их устранять в тот момент, когда их избегают. другие возможные подвиги или проблемы. Хотя я согласен с тем, что угроза такого рода невелика, она все же возникает "
  • 0
    Кроме того, я понимаю различие между Java и ASP-MVC и не пытаюсь переворачивать одно поверх другого. Однако я ожидаю, что смогу сказать, соответствует ли то, что я ожидаю, тому, что я излучаю. И, конечно, не из-за параноика, но, сказав это, - это проект Microsoft.
Показать ещё 5 комментариев
0

@ignatandrei из ASP.NET ответил на вопрос:

по умолчанию MVC преобразует пустую строку в пустую строку.

http://forums.asp.net/t/2006146.aspx?Custom+Validation+and+NULL

  • 0
    Я не думаю, что это влияет на Request.Form ... была причина, по которой вам не понравилось это решение? Например, вы можете посмотреть на AllKeys и увидеть, что ключа там нет.
  • 0
    Пожалуйста, объясните, что вы имеете в виду? Я не думаю, что вы понимаете мой первоначальный вопрос или этот ответ.
Показать ещё 16 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню