4

我正在尝试为 URI 类启用 IDN/IRI 支持,因为我需要德语变音符号域(例如 www.bücher.de)上的“Uri.IsWellFormedUriString”方法。

我在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中进一步阅读了一个偶然发现

Uri 类中的 IRI 和 IDN 处理也可以使用 System.Configuration.IriParsingElement、System.Configuration.IdnElement 和 System.Configuration.UriSection 配置设置类来控制。System.Configuration.IriParsingElement 设置启用或禁用 Uri 类中的 IRI 处理。System.Configuration.IdnElement 设置启用或禁用 Uri 类中的 IDN 处理。System.Configuration.IriParsingElement 设置也间接控制 IDN。必须启用 IRI 处理才能进行 IDN 处理。如果禁用 IRI 处理,则 IDN 处理将设置为默认设置,其中使用 .NET Framework 2.0 行为以实现兼容性并且不使用 IDN 名称。

不幸的是,我找不到使用 System.Configuration.IriParsingElement、System.Configuration.IdnElement 和 System.Configuration.UriSection 的示例。我不知道这些是如何使用的...

所以基本上,我的问题归结为:我想在 URI 类中启用 IDN/IRI 支持,但我不知道该怎么做。配置解决方案对我不起作用,所以我想通过代码尝试,但不知道如何。顺便提一句。我也想知道为什么配置的东西不起作用;)

4

2 回答 2

8

这是我的解决方案,经过测试有效。

基本上,您需要更改 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;
    }
    
于 2013-08-30T05:18:04.873 回答
3

我找到了一个解决方案 - 至少对于 app.config 部分。根据http://social.msdn.microsoft.com/Forums/nl-NL/netfxnetcom/thread/56a73dbb-c0d4-4cad-876d-83ad74064393,如果.Net版本,则必须在app.config中添加一行使用较低的 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>
于 2012-01-25T02:21:08.193 回答