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

Я пытаюсь включить поддержку IDN / IRI для класса URI, потому что мне нужен метод "Uri.IsWellFormedUriString" для немецких доменов umlaut (например, 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, но не могу понять, как это сделать. Конфигурационное решение не работает для меня, поэтому я хотел бы попробовать его по коду, но не могу понять, как. Btw. Я также хотел бы знать, почему не работает конфигурация;)

Ответы [ 2 ]

5 голосов
/ 30 августа 2013

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

По сути, вам необходимо изменить значение статических закрытых полей 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;
    }
    
1 голос
/ 25 января 2012

Я нашел решение - по крайней мере для части 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>
...