Сколько условия в "если оговорка" является приемлемым?


Я пытаюсь проверить HTTP-запрос, и сначала я хочу убедиться, что все информация была размещена (и тогда я проверю, правильный формат каждого из входящих данных), поэтому чтобы быть уверенным, что никакая форма спуфинг атаку. Однако, поскольку этот HTTP-запрос POST приходит из формы, и форма содержит почти 40 месторождений, я наткнулся на если пункт такой:

// Here, the if clause has almost 40 conditions to check
// first, second, third, etc. are imaginary names of incoming variables
if (Request["first"] == null || Request["second"] == null || ...)
{
    throw new ApplicationException("Incoming data is incomplete");
}
else
{
    // Now trying to validate the format of incoming data
}

Это нормальный механизм проверки? Есть ли лучший способ сделать это?



5565
23
c#
задан 13 октября 2011 в 06:10 Источник Поделиться
Комментарии
7 ответов

Вы могли бы поставить все ваши имена переменных в массив и перебрать его, что-то вроде этого (псевдокод):

var names = { 'First', 'Second', 'Third' };

for (var name in names) {
if (Request[names[name]] == null) {
throw new ApplicationException('Error');
}
}

// No errors if we reach here

45
ответ дан 13 октября 2011 в 06:10 Источник Поделиться

Выглядит нечитаемым.

Я обычно экстракт такого условия в частный булевой функции и отформатировать его для удобочитаемости. Это будет первым шагом.

Второй рефакторинг может представить себя после этого - возможно, в списке строку, соответствующую имена полей и перебора с просьбой индексатора, проверка на нулевые значения. Это предполагает, что все части , если , по сути, занимаетесь тем же ничтожности проверить. Это по сути то, что @АНТ представляет в своем ответе.

Отвечая на ваш вопрос - сколько условия приемлемы? Это вещь субъективная, но в целом столько, сколько читается. Лично, если смысл из условия не понятно, экстракт метода рефакторинга с хорошим значимое имя-это отличное начало.

32
ответ дан 13 октября 2011 в 06:10 Источник Поделиться

Я бы извлечь проверки в отдельный метод:

if (RequestIsIncomplete(Request))
{
throw new ApplicationException("Incoming data is incomplete");
}
else
{
// Now trying to validate the format of incoming data
}

private bool RequestIsIncomplete(Request request)
{
if (request["First"] == null)
return false;

if (request["second"] == null)
return false;

// etc...

return true;
}

Отделяя решение от рутинной работы, это хорошая победа. Как пехотинца-дело отделенным, ты волен переписать ее как надо (честно, не оставляйте его так, как я сделал это здесь - видеть Муравьев ответа).

27
ответ дан 13 октября 2011 в 08:10 Источник Поделиться

Я не знаю, какой язык вы используете (возможно c#?) но вы должны иметь в виду поля передачи данных как коллекцию, а не перечислять их по отдельности. Я думаю, что вы должны сделать это в объектно-ориентированное программирование с использованием объекта форма, которая содержит объекты области.

Это очень грубый пример того, что я имею в виду. Вы могли бы иметь поле интерфейса, реализуемый конкретными классами поле как int, текст, файл и т. д.

class Field {
public bool isValid = true;
public string errorMessage;
public string value;
public Field(string name, string label, string type, bool required) {

}
}
class Form {
public List<Field> fields;
public bool isValid = false;
public void validate() {
foreach(Field field in fields) {
if(field.required && field.value = "") {
this.isValid = false;
field.isValid = false;
field.errorMessage = field.name+" field is required";
}
}
}

public void loadData(Array request) {
//stuff the request data into the field objects
foreach(KeyValuePair<string, string> kvp in request) {
fields.Where(x => x.name = kvp.Key).first().value = kvp.value;
}
}
}

По вашему запросу посте вы могли бы сделать это

Form form = new Form();
//name, type, required
form.fields(new Field('field1','text',true);

if(Page.IsPostBack) {
form.loadData(Request);
form.Validate();
if(!form.isValid) {
//print some errors or whatever
throw new Exception(...);
}
}

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

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

8
ответ дан 13 октября 2011 в 09:10 Источник Поделиться

В любом случае-заявление системы П. является приемлемым при условии, что он легко читаем и понятен.

Во-первых, когда количество предложений превышает один (1), Поставить каждое предложение в скобках. Таким образом, вы не должны думать о операторов.

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

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

Я бы перекодировать ваш пример:

if (     ( Request[ "first"  ] == null )
|| ( Request[ "second" ] == null )
|| ( Request[ "third" ] == null )
|| (...) )
{

В-четвертых, если условия привлечения и И ИЛИ, обязательно parenthesise в подпунктах а также изменить отступы, чтобы показать, что Пайс oare компоненты другие фигуры. И, когда он получает этот комплекс, думаю о разбить его на несколько частей, если-отчетность.

6
ответ дан 13 октября 2011 в 08:10 Источник Поделиться

Вы могли бы сделать это проще с помощью LINQ.

var requiredFiels = new [] { "First", "Second", ... };
if (requiredFields.Any(x => Request[x] == null))
throw new ApplicationException(...);

Я думаю, что я бы взял другой подход, хотя. Я бы, наверное, разработала приложение после подхода, управляемого домена. Это значит, что я уже бы классы в моей системе, представляющей хозяйствующих субъектов, к которым эти данные в форме принадлежит. Я бы тогда просто заполните доменных объектов с данные, размещенные в форме, и возложить ответственность проверки данных в области самого объекта.

Однако ни один из этих методов предотвратить вас от формы атаки (которой ты сказал Была цель). Чтобы предотвратить это, вы должны использовать анти-подделки маркер.

3
ответ дан 6 ноября 2011 в 05:11 Источник Поделиться

Вы получили хорошие ответы для упрощенной проверки всех полей. Если это не так, я предлагаю инкапсуляция проверить.

Создать объект, который является validHTTPrequest. В нем есть все сорок своих полей и значения для того, что вы считаете правильным. Возьмите свои входные значения, и назначить их на новый объект, а затем сделать проверку равенства. Если ты перегрузил оператор "равно" на этот объект, чтобы проверить это ВАР и посмотреть, если они совпадают, то вы решили проблему.

Затем ваше заявление будет:

if (currentRequest = validRequest)
{
//do stuff
}
else
{
throw new ApplicationException("Incoming data is incomplete");
}

Если определение действительного запроса не меняется, вы просто измените инициализации объекта vaildRequest.

2
ответ дан 13 октября 2011 в 02:10 Источник Поделиться