Почему Uri.TryCreate выбрасывает NRE, когда url содержит турецкий символ?

Я столкнулся с интересной ситуацией, когда я получаю метод NRE от Uri.TryCreate, когда он должен возвращать false.

Вы можете воспроизвести проблему, как показано ниже:

Uri url;
if (Uri.TryCreate("http:Ç", UriKind.RelativeOrAbsolute, out url))
{
    Console.WriteLine("success");
}

Я думаю, что это не удается во время разбора, но когда я пытаюсь "http:A", например, он возвращает true и анализирует его как относительный URL. Даже если сбой при анализе, он должен просто вернуть false, насколько я понимаю, что может быть проблемой здесь? Это похоже на ошибку в документации по реализации, которая не упоминает об исключении этого метода.

Ошибка возникает в .NET 4.6.1, но не 4.0

Ответ 1

Это ошибка в .NET Framework. Вы можете открыть билет на MicrosoftConnect.

Исключение будет выражено в этом методе

void Systen.Uri.CreateUriInfo(System.Uri.Flags cF)

в строке 2290 (проверьте справочный источник), выполнив следующую инструкцию:

// This is NOT an ImplicitFile uri
idx = (ushort)m_Syntax.SchemeName.Length;

В это время объект m_Syntax будет null, потому что во время разбора он будет отброшен.

Метод

void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)

строка 121:

if (m_Syntax.IsSimple)
{
    if ((err = PrivateParseMinimal()) != ParsingError.None)
    {
        if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
        {
            // RFC 3986 Section 5.4.2 - http:(relativeUri) may be considered a valid relative Uri.
            m_Syntax = null; // convert to relative uri
            e = null;
            m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
         }
         // ...
     }
    // ...
 }

Метод PrivateParseMinimal() возвращает ParsingError.BadAuthority и uriKind == UriKind.RelativeOrAbsolute по вашей спецификации.

Метод PrivateParseMinimal() ищет любую из следующих последовательностей символов: "//", "\", "/\", "/". И поскольку в вашей строке ввода нет таких последовательностей, возвращается код ParsingError.BadAuthority.