| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > Защита от дурака |
| Автор: myendlessness 15.7.2009, 16:35 |
| Предположим есть TextBox, в который вводится определённый адрес, в данном случае ftp, например: ftp.mail.ru! В программе человек будет самостоятельно вводить адрес фтп-сервера, как сделать так чтобы была проверка на правильность введения, чтобы не было невнимательных ошибок и опечаток, что-то вроде: ftp2.mail.ru, ftp.mailru, ftpmail.ru, ftp.mail.ru.ru и прочих изобретательностей. Речь идёт о любом фтп-сервере. Как сделать такую защиту минимальными усилиями? Спасибо за помощь! |
| Автор: diadiavova 15.7.2009, 16:51 |
| В обработчиках событий Validating и Validated. |
| Автор: Heinzz 15.7.2009, 18:58 |
| разбить текст через Split используя разделитель '.' и проверить два условия: * первая строка =="ftp" * строк 3 шт * опционально - длина последней строки 2 символа |
| Автор: SKrivosein 16.7.2009, 01:14 | ||
| Более-мение стандартное решение как написал diadiavova наставить CausesValidation TextBox-са на true которая спустит событие Validating при уходе фокуса. Можно ещё добавить ErrorProvider который покажет пользователю чего плохо
Да regex возможно в этом случае : ^((ftp)\.[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3})$ |
| Автор: myendlessness 16.7.2009, 12:41 |
| Ребята всем СПАСИБО за помощь ), что означают символы? Где можно почитать? И ещё один момент, дело в том, что адрес сервера может состоять из разного количества слов, например: ftp.mail.ru, ftp.mail.tut.by и тд. Может стоит в цикле проверять каждое слово? или что-нибудь в этом духе, пока перевариваю и думаю как лучше и корректно сделать?! |
| Автор: diadiavova 16.7.2009, 12:58 | ||
Вообще-то проверить корректность адреса, а так же определить отдельные его параметры можно при помощи класса System.Uri
Добавлено через 3 минуты и 29 секунд А на счёт символов читай здесь http://msdn.microsoft.com/ru-ru/library/system.text.regularexpressions.regex.aspx И далее по ссылкам в конце топика(другие ресурсы) |
| Автор: SKrivosein 16.7.2009, 13:55 |
| Регулярные выражения беру как общий случай, допустим в техт бокс будеш вводить телефоны, е-майлы и т.д. На книгу лови ссылку:http://www.all-ebooks.com/2006/04/21/regulyarnye_vyrazheniya_e_izd.html Всегда пригодится. P.S. полное выражение про URL: ^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*$ |
| Автор: myendlessness 16.7.2009, 14:48 | ||
diadiavova спасибо за более оптимизированный подход, вот только дойду до 100 сообщений и сразу займусь Вашей репутацией
|
| Автор: diadiavova 16.7.2009, 15:00 |
| Функция работает, надо смотреть другой код. А в приведённом примере, как мне кажется, 10-строку надо тоже в блок if вставить. Объяснялку то в случае ошибки выводить надо. Или я чего-то не понял? |
| Автор: myendlessness 16.7.2009, 15:01 |
| 2 SKrivosein Спасибо за книгу и помощь |
| Автор: SKrivosein 16.7.2009, 15:13 |
| А я если пишу ftp://mail.ru или например ftp://mail.test.ru то всё работает, а ftp.mail.ru нет. Поэтому я свой первый регех написал так: ^((ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3})$ а потом исправил на: ^((ftp)\.[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3})$ и тот первый правильный, а второй... diadiavova if не надо, этот код f.SetError((Control)sender, error); выполнится всегда, но стаботает только если error !=null |
| Автор: myendlessness 16.7.2009, 15:33 |
| diadiavova Вы правильно заметили, что в строчке 10 нужен ещё if, просто у меня это пока пробная версия, тренериюсь и стараюсь понять как всё работает понял почему у меня не срабатывало я пишу: ftp.mail.ru Вы пишите: ftp://mail.ru разница была в том, что нужно полностью (со слешем и двоеточием) писать адрес ВСЕМ СПАСИБО! You are Хотел спросить, как сделать так, чтобы если открылось окно, то нельзя было переходить на другие окна? Добавлено через 9 минут и 24 секунды 2 SKrivosein Вы меня чуть-чуть опередили Значит всё-таки в строчке 10 не надо if! |
| Автор: SKrivosein 16.7.2009, 15:47 |
| Form.ShowDialog(); ? в 10 стрике ничего ненадо, смотреть выше. |
| Автор: myendlessness 16.7.2009, 15:55 |
| Тут возникает один вопрос, какой из двух способов Regex или IsCorrectFtpAddress будет обеспечивать лучшую защиту? |
| Автор: SKrivosein 16.7.2009, 16:08 |
| Всмысле лучшую? Если напишеш правильно рег.выражение то номоему всёравно. Регулярные выражения более универсальны, допустим тебе банк скажет что необходимо проверить вот такого вида ввод: 1234-7746043/asd-0300, здесь нечего стандартного найти нельзя надо самому писать выражение. А IsCorrectFtpAddress это встроеный в .NET метод он 99,99% правильный и голову ламать не надо, но надо знать что он есть |
| Автор: diadiavova 16.7.2009, 16:24 | ||
Вот! Можно, конечно спецификацию изучить Я уже не говорю о том, что чем сложнее регексп, тем труднее контролировать его поведение, а уж о степени читабельности так и говорить нет смысла. В любом случае, если есть возможность воспользоваться готовым прибамбасом, то надо им воспользоваться. По крайней мере будет гарантия, что там всё учтено, включая неизвестные тебе особенности спецификации URL . А когда речь о нестандартном формате, то конечно. Что касается адреса без указания протокола, то тут всё просто, перед проверкой надо с чего начинается строка адреса
Но лучше такую проверку осуществлять перед передачей значения в функцию (добавлять протокол в текстбокс при валидации). |
| Автор: myendlessness 16.7.2009, 16:25 |
| вот простой пример если я пишу ftp://mail или ftp://mail.5ru то есть заведомо неправильно, то IsCorrectFtpAddress пропускает, а регулярные выражения выдают ошибку, то есть это подтверждает, что они более гибкие и если правильно их составить, то и более надёжные, хотя это и логично Добавлено через 3 минуты и 54 секунды 2 diadiavova Дело в том, что ftp:// сразу находится в TextBox при загрузке, то есть "TextBox.text=ftp://" это такая своеобразная подсказка, чтобы изначально не сделали ошибок хотя бы в этом |
| Автор: myendlessness 17.7.2009, 10:24 |
| 2 diadiavova Ну вот ты знаешь, что это заведомо неправильно, а вот для меня это новость. Я не знаю, какие адреса правильные, а какие нет. С другой стороны, что толку если человек введёт корректный, но никуда не ведущий адрес? От всех дураков обезопасить просто невозможно Я хотел спросить как сделать так, чтобы если одна форма запущена, то нельзя было переключится на другую пока не закроешь запущенную? |
| Автор: diadiavova 17.7.2009, 10:26 | ||
"Запущенную" надо запускать при помощи метода ShowDialog (а не Show) |
| Автор: myendlessness 17.7.2009, 10:57 |
| Здорово, спасибо Вам за ответы В развитии темы хотел продолжить, вот скажите человек заносит адрес сервера, дальше надо его запомнить, чтобы при следующей загрузке не надо было заносить ещё раз тоже самое. Как запомнить адрес? Самый простой записать в файл! А когда много всяких параметров, и сохраняются в разное время, то как быть? Либо создавать для каждого параметра свой файл, либо хранить в одном, но как-то его структурировать! А есть ли другие сопсобы сохранения данных? |
| Автор: Raistlin 17.7.2009, 11:16 | ||
Идешь в свойства проекта (Alt-F7), там переходишь на вкладку Settings. Потом читаешь MSDN насчет Properties.Settings. |
| Автор: diadiavova 17.7.2009, 11:16 |
Конечно. Первое, что приходит в голову - база данных. Но если данных не очень много, то можно и более простые средства использовать: XML - файл, настройки программы(Application Settings), последний вариант особенно удобно использовать если надо сохранять состояние элементов управления(например текст в текстбоксе), в этом случае можно всё организовать без единой строчки ручного кода, но даже для хранения других данных ручной код при использовании этого инструмента сильно упростится. http://msdn.microsoft.com/ru-ru/library/k4s6c3a0.aspx |
| Автор: myendlessness 17.7.2009, 12:11 |
| Спасибо за рекомендации, буду разбираться! Хотел уточнить как потом сбрасывать ErrorProvider, если вначале человек ошибся, а затем набрал правильно, то как удалить этот красный кружочек? Думал ErrorProvider.Clear но что-то ничего не убирается. Почитал о членах класса, тоже ничего другого не нашёл. |
| Автор: diadiavova 17.7.2009, 12:56 |
Так же как и устанавливать, только пустую строку передать ему надо в качестве текста сообщения. |
| Автор: SKrivosein 17.7.2009, 14:02 | ||
| Если у тебя все правильно написано то вобще по идее делать не чего не надо. Когда пользователь исправит свой текст и идет дальше, то фокус уходит с текстбокса и срабатывает событие validating которое и уберёт значёк. Разве что ты то в коде что-то поменял, то тогда руками убрать.
P.S. diadiavova я кстати незнал что IsCorrectFtpAddress делает, или так где-то читал но забыл...так же спасибо за напоминание. А по поводу что лучше, так это дело относительное. Я держусь точки зрения буддизма: "все цветы совершенны !" |
| Автор: diadiavova 17.7.2009, 14:10 |
Хочу обратить твоё внимание, что IsCorrectFtpAddress - это имя метода, придуманное мною лично для этой темы, но в нём использован метод IsWellFormedUriString, класса URI. Ну я вроде как аргументировал. Удобство в нашем деле тоже не последний аргумент. Даже если проверять нестандартную строку, то регексп ИМХО всё равно лучше обернуть для удобства. |
| Автор: myendlessness 20.7.2009, 10:02 | ||
Вот мой код, однако всё равно не убирает красный кружочек, даже когда правильно всё прописываю в TextBox? |
| Автор: myendlessness 20.7.2009, 10:22 |
| И ещё вопрос |
| Автор: diadiavova 20.7.2009, 11:29 |
Что это значит? Если ты связал свойство Text текстбокса с параметром, то значение этого свойства будет сохраняться даже после закрытия приложения. Для того, чтобы его сменить, надо просто в текстбоксе написать другую строку. |
| Автор: myendlessness 20.7.2009, 11:43 |
| http://msdn.microsoft.com/ru-ru/library/wabtadw6.aspx вот сделал так как написано в инструкции при помощи конструктора, получилось что есть параматр приложения ftp://mail.ru, имя ему UserTextBox, он пользовательский. Затем я запускаю программу и пишу вместо mail.ru, например mail.tut.by, закрываю программу, однако, при следующей загрузке он всё равно пишет mail.ru. почему он не сохранил изменения? Добавлено через 1 минуту и 33 секунды Спасибо ребята, что помогаете. Узнаю много полезного и нового от Вас и быстро учусь программировать на C#! Добавлено через 10 минут и 26 секунд Всё с этим разобрался, здорово офигенно и теперь всё работает! осталось понять как избавиться от красного кружка в ErrorProvider? Текст исчезает, а красный кружок остаётся! |
| Автор: diadiavova 20.7.2009, 13:06 | ||||||
Ну да, так и есть, просто мне в шарпе не приходилось с этим работать, а в васике всё происходит автоматически
Куда исчезает? Я так понимаю, если текст исчез, значит он не прошёл проверку и предупреждение не должно исчезнуть. По идее код рабочий. |
| Автор: myendlessness 20.7.2009, 14:09 |
| Так вот и я не понимаю, else срабатывает error=null из-за этого текст исчезает, а кружочек остаётся красный и с пустой строкой. |
| Автор: diadiavova 20.7.2009, 14:24 | ||
myendlessness, ерорпровайдер не надо каждый раз создавать, но проблема не в этом... в регулярном выражении.
Создай его с указанной опцией. |
| Автор: myendlessness 21.7.2009, 10:27 | ||
Сделал вот так и всё равно красный кружочек не исчезает, хотя else срабатывает!
|
| Автор: myendlessness 21.7.2009, 10:52 | ||
Хотел ещё спросить по поводу оптимизации, как вот такой код сделать коротким? Повторяющиеся CheckBox связанные с TextBox
|
| Автор: diadiavova 21.7.2009, 11:12 | ||||||
Ты передаёшь провайдеру пробел, а надо - пустую строку. Просто пару кавычек рядом поставь и никаких пробелов между ними. Тот же эффект будет при null и при string.Empty Вместо
надо написать
С остальными - так же. Можно ещё связать свойства и тогда писать вообще ничего не придётся. В окне свойств разберись с пунктом DataBinding (в мсдн всё есть) |
| Автор: myendlessness 21.7.2009, 15:24 |
| Спасибо за помощь, всё заработало. 2 diadiavova Подскажите пожалуйста, а если я использую Scheme == "file" , то как правильно прописывается путь файла на локальной машине, как правильно написать escape-последовательность, что-то я и так и сяк, но он не принимает? и если кому не трудно, то напишите, пожалуйста,как будет выглядеть регулярное выражение, для файла на компьютере? |
| Автор: diadiavova 21.7.2009, 15:32 | ||
Не совсем понял о чём речь, видимо вопрос в том, как записать имя файла, чтобы обратные слэши воспринимались как есть. Либо писать 2 слэша вместо одного, либо перед строкой ставить собачку.
Хотя в коде писать имя файла не стоит, разве что относительное. А если речь о проверке пути, то по строке не надо проверять. Для этого есть классы пространства System.IO. Например System.IO.FileInfo вполне подойдёт. |
| Автор: myendlessness 21.7.2009, 16:12 |
| diadiavova Вы просто святой человек |
| Автор: diadiavova 21.7.2009, 17:17 |
Это да |
| Автор: myendlessness 22.7.2009, 14:16 | ||
ЧТо касается проверки локального адреса, существует ли такой каталог, то я написал такой код
С одной стороны первой проверки вроде достаточно, так как если символ будет некорректный, то она выдаст что такого каталога нет, однако, возможно есть такие варианты, которые может пропустить первая проверка, хотя может это излишняя перестраховка? Вот возникает вопрос а если человек напишет - С:///\\\Admin/..\Books точно схавает этот адрес, а как после того как адрес пройдёт, привести его в человеческий вид, чтобы можно было дальше работать? |
| Автор: diadiavova 22.7.2009, 17:35 | ||
Directory.Exists не просто строку проверяет, этот метод разбирает её и выясняет, существует ли такой каталог. Со строкой лучше не заморачиваться когда есть готовый метод(почему - писал выше).
С чего бы это? |
| Автор: myendlessness 23.7.2009, 11:24 | ||
diadiavova По ходу пьесы возникло ещё несколько вопросов, насчёт той стандартной проверки которую предложили Вы, а именно:
То я ввожу разные варианты адреса, и в том числе что описаны выше, а он не хочет их принимать пишет неправильный адрес, не могу понять, как правильно записывать file-строку в этом методе? Так всё-таки стоит использовать только Directory.Exists? или лучше Uri.IsWellFormedUriString? И ещё вопросик, вот я подключаю свои библиотеки и естественно прописываю адрес, а как сделать так чтобы при переносе на другой компьютер, не надо было прописывать повторно новый адрес, то есть записать так чтобы программа сама их всегда находила в нужной папке? |
| Автор: diadiavova 23.7.2009, 11:31 | ||||||||
Не так, а так
Добавлено через 4 минуты и 6 секунд
Смотря где, если надо проверить существование каталога, то экзист, а если корректность адресной строки...
Если они в папке с программой, то можно находить по относительному адресу, а в других случаях, если библиотека зарегистрирована, то можно по гуиду например, но вопрос надо уточнить, что за библиотеки. Добавлено через 13 минут и 9 секунд Проверил работу функции для файловой системы. Действительно выдаёт фальс. Проблема решается передачей строки в таком формате вместо c://doc/aaa.txt надо писать file:///c://doc/aaa.txt Хотя из обычной строки объект Uri создаётся, поэтому можно его просто создать и всё, а можно сначала(как я уже предлагал) проверить с чего начинается адрес, и в случае если это не file:/// просто добавить эту строку в начало. Тут есть варианты. PS И имя функции неплохо бы поменять на более подходящее для задачи |
| Автор: myendlessness 4.8.2009, 12:15 | ||
| Ребята вновь возник вопрос по ходу работы! Есть такой код, в общем получаю рисунок:
Затем мне дальше нужно использовать этот рисунок, пишу такой код: FileStream Tiff = new FileStream(ofd.FileName, FileMode.Open); на что мне выдаёт ошибку: Процесс не может получить доступ к файлу , так как этот файл используется другим процессом. Как мне использовать рисунок в нескольких процессах? |
| Автор: diadiavova 4.8.2009, 13:16 | ||
Для нового вопроса надо создавать новую тему. |