Для безопасности и согласованности я бы хотел проверить на пост-обратно, если поле отсутствует? В 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: Я тщательно очистил код вопроса и примера, чтобы сделать его намного понятнее, надеюсь, что это поможет.
Если вам нужен собственный валидатор, вы можете посмотреть словарь HttpContext.Current.Request.Form
. Затем вы можете сделать то, что вы предложили с помощью этого кода:
if (!HttpContext.Current.Request.Form.AllKeys.Contains("prop"))
{
throw new Exception();
}
Вам не хватает одного важного момента - при отправке формы все поля, относящиеся к этой форме, отправляются. Если пользователь не заполняет их, они пусты, поэтому проверка для null не может работать так...
Вероятно, вам следует переопределить, что означает "недостающее значение".
РЕДАКТИРОВАТЬ:
После некоторого обсуждения кажется, что вас действительно не интересуют нулевые значения, а о безопасности (ложные формы с отсутствующими полями и тому подобное). В этом случае вы должны просто использовать стандартную марку antiforgery и, возможно, проверить происхождение запроса. Вы должны быть более чем прекрасным таким образом. Проверка недостающих полей не поможет, потому что злоумышленник может легко отправить эти поля.
Перегрузка/Под проводкой является реальной проблемой. Кроме того, если поля не отправлены (из-за какой-либо взлома или атаки DOS)
На самом деле, нет.
Overposting обрабатывается методом действия на контроллере. Он не будет принимать больше параметров, чем вы указали.
Underposting будет обрабатываться почти так же, как если бы вы не заполняли текстовые поля в форме, опять же без проблем, если вы правильно подтвердили свою модель.
DDOS-атака не может быть предотвращена, поверьте, некоторые проверки отсутствующих полей не помогут, если у кого-то есть сеть, достаточно мощная, чтобы вызвать DDOS. Просто просмотрите последние случаи при атаках, и вы поймете, что если ОГРОМНЫЕ серверы не могут этого выдержать, вы, конечно же, не сможете это предотвратить.
Ваша проверка данных также не должна быть слишком дорогостоящей. Это веб, люди не любят ждать слишком много.
Я думаю, вы здесь необоснованно параноичны. Заметьте, что я сказал, что необоснованно параноидально, так как небольшая паранойя - это хорошо.
Во-первых, давайте проанализируем "угрозы" и определим риски. Вы представили несколько аргументов:
Первый элемент не является проблемой в MVC, если вы используете View Model. Вы просто не можете публиковать информацию, которую вид не ожидает (ну, можно, но он игнорируется). Если вы не используете модель представления (или не используете правильно определенный), вы можете использовать атрибуты привязки, чтобы предотвратить публикацию элементов, которые вы не хотите связывать.
Второе, недопоставление, если это действительно является проблемой для вашей модели (99.999% времени, просто рассматривая ее по мере необходимости, более чем нормально, но нормально давайте рассмотрим ваш аргумент. Проблема здесь не в атрибуте проверки, это модель вам просто нужно зарегистрировать настраиваемое связующее устройство, которое ищет отсутствующие значения в вашей модели представления и выбрасывает, если они равны нулю. Это легко осуществить, отразив над связанной моделью и сравнив ее с опубликованными значениями, а затем выбросьте.
Проблема с вашим подходом RequiredThrowIfNull заключается в том, что, если это не требуется, и оно опубликовано? Это все еще ошибка в соответствии с вашими аргументами.
Наконец, проверка пустых vs null... вы говорите о дорогостоящей проверке... Я не знаю, какую дорогостоящую проверку вы могли бы здесь говорить, но на стороне сервера отмечается атрибуты, которые можно считать дорогостоящими.
Причина, по которой ваш атрибут не работает, заключается в том, что атрибуты проверки уже включены в блок try/catch уже с помощью фреймворка, и если он обнуляет его, тот самый механизм, который обрабатывает его как пустым (этот механизм также делает такие вещи, как ловли ошибки синтаксического анализа, когда тип неверен, например, символы в поле даты и времени.)
.NET не является Java, хотя он в значительной степени работает аналогично... попытка повторной реализации шаблонов Java в.NET будет приводить к нищете с вашей стороны, потому что многие базовые философии просто разные.
Даже если мы примем ваш аргумент о желании поймать ошибки или быть уведомлены о попытках взлома, бросать в большинстве случаев неправильно. Вместо этого просто зарегистрируйте информацию из привязки модели и продолжайте работу в обычном режиме. Бросьте только, если вам абсолютно необходимо отменить запрос, и большую часть времени это просто не так, даже если вас взломали. Бросок просто заставит атакующего изменять свою атаку, пока они больше не получат исключение.
Честно говоря, это переработанное решение, которое ищет проблему, и есть много хороших.net конкретных способов решения проблем, которые вы пытаетесь решить.
@ignatandrei из ASP.NET ответил на вопрос:
по умолчанию MVC преобразует пустую строку в пустую строку.
http://forums.asp.net/t/2006146.aspx?Custom+Validation+and+NULL