Как проверить правильность строки uri

82

Как вы проверяете, что строка uri действительна (что вы можете передать ее конструктору Uri)?

Пока у меня есть только следующее, но по очевидным причинам я бы предпочел менее грубый способ:

    Boolean IsValidUri(String uri)
    {
        try
        {
            new Uri(uri);
            return true;
        }
        catch
        {
            return false;
        }
    }

Я попробовал Uri.IsWellFformedUriString, но, похоже, ему не нравится все, что вы можете бросить в конструктор. Например:

String test = @"C:\File.txt";
Console.WriteLine("Uri.IsWellFormedUriString says: {0}", Uri.IsWellFormedUriString(test, UriKind.RelativeOrAbsolute));
Console.WriteLine("IsValidUri says: {0}", IsValidUri(test));

Результат будет:

Uri.IsWellFormedUriString says: False
IsValidUri says: True

Обновление / ответ

Конструктор Uri по умолчанию использует вид Absolute. Это вызывало несоответствие, когда я пытался использовать Uri.TryCreate и конструктор. Вы получите ожидаемый результат, если сопоставите UriKind как для конструктора, так и для TryCreate.

Мануэль
источник

Ответы:

82

Правильно сформированный URI подразумевает соответствие определенным RFC. Локальный путь в вашем примере не соответствует им. Подробнее читайте в IsWellFormedUriStringдокументации.

Ложный результат этого метода не означает, что Uriкласс не сможет проанализировать ввод. Хотя вводимый URI может не соответствовать RFC, он все же может быть действительным URI.

Обновление : И чтобы ответить на ваш вопрос - как показывает документация Uri, существует статический метод, TryCreateкоторый будет пытаться именно то, что вы хотите, и вернуть true или false (и фактический Uriэкземпляр, если true).

Франси Пенов
источник
Возникает вопрос: «Как вы проверяете, что строка uri действительна (что вы можете передать ее конструктору Uri)?»
Мануэль
1
TryCreate на самом деле не сообщает вам, будет ли строка принята конструктором. См. Обновление.
Мануэль
@Manuel: это вообще не имеет смысла - результат TryCreateи Uriконструктор должны быть идентичными - попробуйте передать то же самое, UriKindчто и для TryCreate.
BrokenGlass
1
Вы правы. Конструктор использует вид по умолчанию Absolute. Благодарю.
Мануэль
3
Согласно источникам .Net, метод IsWellFformedUriString содержит вызов метода TryCreate плюс дополнительные проверки , поэтому я предпочитаю использовать метод IsWellFformedUriString как более мощный для таких задач.
Игорь Кустов
43

Поскольку в принятом ответе нет явного примера, вот код для проверки URI на C #:

Uri outUri;

if (Uri.TryCreate("ThisIsAnInvalidAbsoluteURI", UriKind.Absolute, out outUri)
   && (outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps))
{
    //Do something with your validated Absolute URI...
}
DiscDev
источник
2
Не доверяйте функции Uri.TryCreate! Это также позволит использовать неверные URL-адреса. Попробуйте это http: // http: // google.com/page (удалите пробелы). Этот URL-адрес передает функцию TryCreate, но это неверно.
No1Lives4Ever
5
@ No1Lives4Ever Вы правы, что он анализирует как действительное то, что вы упомянули, но технически это не так. Объяснение на английском языке: используя протокол http ( http: // ), подключитесь к записи DNS для «http» (http: // ** http **), используя явный (но опущенный) порт ( http **: * *) - так что я буду использовать протокол по умолчанию; вы предоставили пустую папку первого уровня ( http : ** // **), но я знаю, что вы имели в виду;), за которой следует сегмент пути "google.com" ( http: / ** google.com / **), а затем ресурс "страница" ( http://google.com ** page **)
mlhDev
9

Предполагая, что мы хотим поддерживать только абсолютные URI и HTTP-запросы, вот функция, которая делает то, что вы хотите:

public static bool IsValidURI(string uri)
{
    if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))
        return false;
    Uri tmp;
    if (!Uri.TryCreate(uri, UriKind.Absolute, out tmp))
        return false;
    return tmp.Scheme == Uri.UriSchemeHttp || tmp.Scheme == Uri.UriSchemeHttps;
}
cdiggins
источник
1
Вторая проверка необходима, чтобы сделать возможной третью (и последнюю) проверку. Без него нет tmp. Первый шаг в данном случае, возможно, излишен ...
Джо
1

В моем случае я просто хотел протестировать uri, я не хочу замедлять приложение, тестирующее uri.

Boolean IsValidUri(String uri){
  return Uri.IsWellFormedUriString(uri, UriKind.Absolute);
}
Глаубер Родригес
источник
0

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

Виджей Сиригири
источник
Я использую UriKind.RelativeOrAbsolute, поэтому это не имеет значения. В любом случае это не работает с UriKind.Relative или UriKind.Absolute, так что не повезло.
Мануэль