C # asp.net построить SQL-запрос динамически из viewstate - PullRequest
0 голосов
/ 25 января 2009

В моей веб-форме на C # asp.net у меня есть страница поиска, содержащая примерно 20 элементов, которые «могут» использоваться как часть поиска. Позже будет добавлено больше.

Я расширил текстовое поле и раскрывающийся список, включив в него несколько переменных:

fieldname: Tablename.columnname dbtype: DbType.Int32 Joinparam: LEFT Присоединиться к другой таблице ВКЛ. X.y = a.b

Все они хранятся в viewstate и загружаются обратно. Причина, по которой я это делаю, состоит в том, чтобы я мог перебирать все элементы управления и извлекать все элементы управления моего типа. Затем я могу проверить их, чтобы убедиться, что они имеют ввод и имеют правильный тип. В таком случае я могу передать их на уровень доступа к базе данных и позволить коду динамически генерировать оператор SQL.

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

Меня беспокоит то, что я поместил имена таблиц и полей, которые будут использоваться в критериях поиска, и требуемые JOINS все в состоянии просмотра. Это действительно плохая идея?

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

Причина, по которой я пошел на такой подход, заключалась в том, что я не хотел помещать тонны операторов IF в слой DB, чтобы построить там оператор. Это было бы ужасно, черт возьми, и боль, чтобы поддерживать.

Спасибо за любые советы по этому поводу.

Jon

EDIT

Спасибо всем за совет. К счастью, это приложение только для внутреннего использования, поэтому ущерб будет ограничен. Но я больше никогда не буду использовать эту технику и вместо этого буду работать над идеей шаблона поиска.

Приветствия:)

Ответы [ 3 ]

3 голосов
/ 25 января 2009

Я думаю, что это настоящая ошибка проектирования - кодировать части уровня доступа к данным в логике вашего представления. Оставляя в стороне проблемы безопасности, это будет действительно трудно поддерживать и понимать для любого, кто придет после вас. Я думаю, что фабричный класс для создания ваших конкретных запросов из различных выбранных входов, вероятно, будет легче работать в долгосрочной перспективе. Или, возможно, вы можете заполнить «шаблон поиска» из входных данных и использовать функцию шаблона поиска в качестве фабрики для создания запроса, во многом как способ взаимодействия UserPrincipal с PrincipalSearcher в пространстве имен System.DirectoryServices.AccountManagement.

2 голосов
/ 25 января 2009

Viewstate не зашифровано, оно закодировано в base64. Доступны утилиты, которые позволят вам декодировать состояние просмотра страницы.

Возможно зашифровать состояние просмотра для страницы или всех ваших страниц, однако: http://msdn.microsoft.com/en-us/library/aa479501.aspx

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

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

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

1 голос
/ 25 января 2009

Хорошо, поэтому ViewState по умолчанию имеет значение MACed и может быть зашифрован. Таким образом, хотя вы можете (по умолчанию) читать viewstate, вмешательство не является тривиальным .

Построение вашего запроса динамически, как это, безусловно, откроет вам доступ к Sql Injection - вы настраиваете условия поиска, но если я могу вставить оператор; DROP TABLE в ваше предложение JOIN, вы попадаете (если вы не конечно, позаботился о том, чтобы установить безопасность на уровне БД).

При этом я не вижу никакой причины, по которой ваши предложения JOIN и тому подобное должны быть во ViewState. Я думаю, вы задали бы их как свойства вашего подкласса в разметке ASPX - нет причин для их изменения. Единственное, для чего вам может понадобиться ViewState - это само условие поиска, которое соответствующим образом параметризовано. Это похоже на то, как SqlDataSource защищает свое свойство SelectCommand - не храните его во ViewState, чтобы не пропустить информацию (или рисковать подделкой - хотя я не думаю, что это серьезная уязвимость).

Что касается более широкого вопроса о том, можно ли это обслуживать - ну, я полагаю, вам придется сделать этот вызов.

...