Как включить поддержку IDN / IRI для URI-класса по коду?

Я пытаюсь включить поддержку IDN / IRI для класса URI, потому что мне нужен метод «Uri.IsWellFformedUriString» на немецких доменах умлаута (например, www.bücher.de).

Я нашел аналогичный вопрос в https://stackoverflow.com/a/6107682/413531 (взято из http://msdn.microsoft.com/en-us/library/system.uri.aspx в разделе «Поддержка международных идентификаторов ресурсов»), но решение у меня не работает. Мой текущий файл app.config выглядит примерно так:

<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="..." type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        <!-- ... some sections in here ... -->
        </sectionGroup>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <!-- ... some sections in here ... -->
        </sectionGroup>
    </configSections>
    <userSettings>
        <!-- ... some settings in here ... -->
    </userSettings>
    <applicationSettings>
        <!-- ... some settings in here ... -->
    </applicationSettings>
</configuration>

когда я просто добавляю

  <uri>
  <idn enabled="All" />
  <iriParsing enabled="true" />
  </uri>

как другой дочерний элемент в конце, создается исключение: ConfigurationErrorsException - {"Das Konfigurationssystem konnte nicht initialisiert werden."}

Я читаю дальше в http://msdn.microsoft.com/en-us/library/system.uri.aspx наткнулся на

Обработкой IRI и IDN в классе Uri также можно управлять с помощью классов параметров конфигурации System.Configuration.IriParsingElement, System.Configuration.IdnElement и System.Configuration.UriSection. Параметр System.Configuration.IriParsingElement включает или отключает обработку IRI в классе Uri. Параметр System.Configuration.IdnElement включает или отключает обработку IDN в классе Uri. Параметр System.Configuration.IriParsingElement также косвенно управляет IDN. Обработка IRI должна быть включена для возможности обработки IDN. Если обработка IRI отключена, для обработки IDN будет установлено значение по умолчанию, при котором поведение .NET Framework 2.0 используется для совместимости, а имена IDN не используются.

К сожалению, мне не удалось найти пример использования System.Configuration.IriParsingElement, System.Configuration.IdnElement и System.Configuration.UriSection. Понятия не имею, как они используются ...

В общем, моя проблема сводится к следующему: я хочу включить поддержку IDN / IRI в классе URI, но не могу понять, как это сделать. Конфигурационное решение у меня не работает, поэтому я хотел бы попробовать его по коду, но не могу понять, как это сделать. Кстати. Я также хотел бы знать, почему не работает конфиг;)


person Hirnhamster    schedule 12.01.2012    source источник


Ответы (2)


Это мое решение, проверенное сработало.

По сути, вам нужно изменить значение статических закрытых полей System.Uri:

  • s_IdnScope
  • s_IriParsing

    public static bool ToggleIDNIRISupport(bool enable)
    {
        //Important: Try IsWellFormedUriString() once to initialize static fields: s_IdnScope, s_IriParsing
        Uri.IsWellFormedUriString("http://example.com/query=ü", UriKind.Absolute);
    
        //Get the assembly that contains the class
        Assembly assembly = Assembly.GetAssembly(typeof(Uri));
        if (assembly != null)
        {
            //Use the assembly in order to get the type of the class
            Type uriType = assembly.GetType("System.Uri");
            if (uriType != null)
            {
                object idnScope = uriType.InvokeMember("s_IdnScope", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic, null, null, new object[] { });
                if (idnScope != null)
                {
                    if (enable)
                    {
                        uriType.InvokeMember("s_IdnScope", BindingFlags.Static | BindingFlags.SetField | BindingFlags.NonPublic, null, null, new object[] { UriIdnScope.All });
                    }
                    else
                    {
                        uriType.InvokeMember("s_IdnScope", BindingFlags.Static | BindingFlags.SetField | BindingFlags.NonPublic, null, null, new object[] { UriIdnScope.None });
                    }
                }
    
                object iriParsing = uriType.InvokeMember("s_IriParsing", BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic, null, null, new object[] { });
                if (iriParsing != null)
                {
                    uriType.InvokeMember("s_IriParsing", BindingFlags.Static | BindingFlags.SetField | BindingFlags.NonPublic, null, null, new object[] { enable });
                }
            }
        }
    
        return true;
    }
    
person MDK. dc    schedule 30.08.2013

Я нашел решение - по крайней мере, для части app.config. Согласно http://social.msdn.microsoft.com/Forums/nl-NL/netfxnetcom/thread/56a73dbb-c0d4-4cad-876d-83ad74064393 необходимо добавить дополнительную строку в app.config, если .Net версии ниже 4.0 использовал:

<configSections>
  <section name="uri" type="System.Configuration.UriSection, System,
                      Version=2.0.0.0, Culture=neutral,
                      PublicKeyToken=b77a5c561934e089" />
</configSections>

После добавления этой строки я мог бы также добавить

<uri>
    <idn enabled="All" />
    <iriParsing enabled="true" />
</uri>

без ошибок. Мой полный app.config теперь выглядит так:

<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="..." type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    <!-- ... some sections in here ... -->
        </sectionGroup>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
    <!-- ... some sections in here ... -->
        </sectionGroup>

<!-- ... insert Missing section ... -->

        <section name="uri" type="System.Configuration.UriSection, System,
                      Version=2.0.0.0, Culture=neutral,
                      PublicKeyToken=b77a5c561934e089" />

    </configSections>

<!-- ... insert URI settings ... -->

    <uri>
        <idn enabled="All" />
        <iriParsing enabled="true" />
    </uri>

    <userSettings>
    <!-- ... some settings in here ... -->
    </userSettings>
    <applicationSettings>
    <!-- ... some settings in here ... -->
    </applicationSettings>
</configuration>
person Hirnhamster    schedule 25.01.2012