2012-01-12 1 views
2

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

Я нашел аналогичный вопрос на 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 könnte Nicht initialisiert Верден. "}

Так что я прочитал дальше в 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 не используются.

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

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

ответ

1

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

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

В принципе, вам необходимо изменить значение статических непубличных полей системы.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; 
    }