Как проверить, является ли строка действительным HTTP-URL?

251

Есть в Uri.IsWellFormedUriStringи Uri.TryCreateметоды, но они , кажется , чтобы вернуться trueна пути к файлам и т.д.

Как проверить, является ли строка действительным (не обязательно активным) HTTP-URL для проверки входных данных?

Луис Рис
источник
Не используйте regex.IsMatch для проверки URL. Может убить процессор. stackoverflow.com/questions/31227785/…
inesmar

Ответы:

452

Попробуйте это проверить HTTP-URL ( uriNameэто URI, который вы хотите проверить):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && uriResult.Scheme == Uri.UriSchemeHttp;

Или, если вы хотите принять действительные URL-адреса HTTP и HTTPS (согласно комментарию J0e3gan):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
Арабела Паслару
источник
6
Должно ли это читать uriResult.Scheme вместо uriName.Scheme? Я использую перегрузку для TryCreate, которая принимает String вместо Uri в качестве первого параметра.
7
Вы можете добавить дополнительные условия в uriResult.Scheme == ... В частности, https. Это зависит от того, для чего вам это нужно, но это небольшое изменение - все, что мне нужно для того, чтобы он идеально работал для меня.
Fiarr
11
Для ясности в комментарии @ Fiarr, «небольшое изменение», необходимое для учета HTTPS в дополнение к URL-адресам HTTP:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan
3
этот путь не работает для URL, как abcde . Это говорит, что это действительный URL.
Кайлаш П
7
Похоже, что эта техника не проходит 22 из 75 тестов dotnetfiddle.net/XduN3A
whitneyland
98

Этот метод отлично работает как в http и https. Всего одна строчка :)

if (Uri.IsWellFormedUriString("https://www.google.com", UriKind.Absolute))

MSDN: IsWellFormedUriString

Kishath
источник
13
Это возвращает истину для не-HTTP URI , (то есть какой - либо другой схемы , такие как file://или ldap://это решение должно быть соединено с чеком против схемы -. Напримерif (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
закорючка
Соответствует ли это RFC3986?
Маркус
3
@Squiggle Это именно то, что я хочу, чтобы он проверил, все, так как я делаю Downloader. Так что этот ответ - лучший метод для меня.
Бейондо
24
    public static bool CheckURLValid(this string source)
    {
        Uri uriResult;
        return Uri.TryCreate(source, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp;
    }

Использование:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}

ОБНОВЛЕНИЕ: (одна строка кода) Спасибо @GoClimbColorado

public static bool CheckURLValid(this string source) => Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps;

Использование:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}
Эрчин Дедеоглу
источник
Это не похоже на работу с URL-адресами www. IE: www.google.com отображается как недействительный.
Заубер Парацельс
6
@ZauberParacelsus "www.google.com" недействителен. Значение URL должно начинаться с "http", "ftp", "file" и т. Д. Строка должна быть без пробела "http: // www.google.com"
Erçin Dedeoğlu
1
Сегодня параметр out может улучшить Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
ситуацию
11

Все ответы здесь либо разрешить URL - адрес с другими схемами (например, file://, ftp://) или отклонить удобочитаемых URL , которые не начинаются с http://или https://(например, www.google.com) , которые не очень хорошо при работе с вводимым пользователем .

Вот как я это делаю:

public static bool ValidHttpURL(string s, out Uri resultURI)
{
    if (!Regex.IsMatch(s, @"^https?:\/\/", RegexOptions.IgnoreCase))
        s = "http://" + s;

    if (Uri.TryCreate(s, UriKind.Absolute, out resultURI))
        return (resultURI.Scheme == Uri.UriSchemeHttp || 
                resultURI.Scheme == Uri.UriSchemeHttps);

    return false;
}

Использование:

string[] inputs = new[] {
                          "https://www.google.com",
                          "http://www.google.com",
                          "www.google.com",
                          "google.com",
                          "javascript:alert('Hack me!')"
                        };
foreach (string s in inputs)
{
    Uri uriResult;
    bool result = ValidHttpURL(s, out uriResult);
    Console.WriteLine(result + "\t" + uriResult?.AbsoluteUri);
}

Вывод:

True    https://www.google.com/
True    http://www.google.com/
True    http://www.google.com/
True    http://google.com/
False
Ахмед Абдельхамид
источник
1
Это пропускает отдельные слова, такие как «mooooooooo», но может использоваться в сочетании с Uri.IsWellFormedUriString может быть хорошо
Epirocks
@ Epirocks Это хороший момент. Проблема в том http://mooooooooo, что на самом деле это действительный Uri. Таким образом, вы не можете проверить Uri.IsWellFormedUriStringпосле вставки «http: //», и если вы проверяете его раньше, все, что не имеет, Schemeбудет отклонено. Может быть, то, что можно сделать, это проверить s.Contains('.')вместо этого.
Ахмед Абдельхамид
Само по себе moooooo не выглядит как URL, так как на нем нет протокола. Что я сделал, так это снял ваш вызов на совпадение с регулярным выражением, и также отредактировал его с помощью IsWellFormedUriString.
Epirocks
@ Epirocks Точно! Проблема в том, что если вы используете IsWellFormedUriStringперед добавлением http://, вы в конечном итоге отвергаете такие вещи, как, google.comи если вы используете его после добавления http://, он все равно будет возвращать true для http://mooooooooo. Вот почему я предложил проверить, содержит ли строка .вместо этого.
Ахмед Абдельхамид
В любом случае, это нормально для меня. Я не хочу принимать URL без http или https. Поэтому я сначала использую IsWellFormedUriString, затем использую вашу функцию без регулярных выражений. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Спасибо
Epirocks
5

После Uri.TryCreateвы можете проверить, Uri.Schemeесли это HTTP (s).

Жалкая переменная
источник
3

Попробуй это:

bool IsValidURL(string URL)
{
    string Pattern = @"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$";
    Regex Rgx = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
    return Rgx.IsMatch(URL);
}

Он примет URL так:

  • HTTP (ы): //www.example.com
  • HTTP (ы): //stackoverflow.example.com
  • HTTP (ы): //www.example.com/page
  • HTTP (S): //www.example.com/page ID = 1 & продукт = 2
  • HTTP (ы): //www.example.com/page#start
  • HTTP (ы): //www.example.com: 8080
  • HTTP (ы): //127.0.0.1
  • 127.0.0.1
  • www.example.com
  • example.com
Марко Конкас
источник
2

Это вернуло бы bool:

Uri.IsWellFormedUriString(a.GetAttribute("href"), UriKind.Absolute)
user3760031
источник
2
Я думаю, что ОП упомянул, ему не нравится Uri.IsWellFormedUriString, поскольку он дает истину для путей к файлам. У вас есть решение этой проблемы?
Исантипов
1
Uri uri = null;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri) || null == uri)
    return false;
else
    return true;

Вот urlстрока, которую вы должны проверить.

Eranda
источник
3
null == проверка URL ужасно избыточна
JSON
0
bool passed = Uri.TryCreate(url, UriKind.Absolute, out Uri uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)
Ифеани Чукву
источник
Ваш ответ пришел в сообщениях низкого качества. Пожалуйста, предоставьте некоторые объяснения, хотя ваш код говорит само за себя.
Харша Бияни