带有urlencoded字符的System.Net.Uri

我需要在我的应用程序中请求以下URL:

http://feedbooks.com/type/Crime%2FMystery/books/top 

当我运行以下代码时:

 Uri myUri = new Uri("http://feedbooks.com/type/Crime%2FMystery/books/top"); 

Uri构造函数将%2F解码为文字/ ,我得到404错误,因为它已将URL更改为:

 http://feedbooks.com/type/Crime/Mystery/books/top 

Uri类有一个带有参数dontEscape构造函数,但是不推荐使用该构造函数并将其设置为true无效。

我的第一个想法是做一些像:

 Uri myUri = new Uri("http://feedbooks.com/type/Crime%252FMystery/books/top"); 

希望它将%25转换为字面% ,但这也不起作用。

有关如何在.NET中为此特定URL创建正确的Uri对象的任何想法?

我使用2.0遇到了同样的问题……

我在这个博客上发现了一个解决方法:

 // System.UriSyntaxFlags is internal, so let's duplicate the flag privately private const int UnEscapeDotsAndSlashes = 0x2000000; public static void LeaveDotsAndSlashesEscaped(Uri uri) { if (uri == null) { throw new ArgumentNullException("uri"); } FieldInfo fieldInfo = uri.GetType().GetField("m_Syntax", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo == null) { throw new MissingFieldException("'m_Syntax' field not found"); } object uriParser = fieldInfo.GetValue(uri); fieldInfo = typeof(UriParser).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo == null) { throw new MissingFieldException("'m_Flags' field not found"); } object uriSyntaxFlags = fieldInfo.GetValue(uriParser); // Clear the flag that we don't want uriSyntaxFlags = (int)uriSyntaxFlags & ~UnEscapeDotsAndSlashes; fieldInfo.SetValue(uriParser, uriSyntaxFlags); } 

它完美地运作。

希望这会有所帮助(迟到总比没有好!)

它在.NET 4.0中更容易一些。 您可以在配置文件中设置如下设置:

      

它仅适用于’http’和’https’方案。

或者这是LeaveDotsAndSlashesEscaped方法的新版本。 它不需要特定的Uri实例,只需在应用程序启动时调用它:

 private void LeaveDotsAndSlashesEscaped() { var getSyntaxMethod = typeof (UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic); if (getSyntaxMethod == null) { throw new MissingMethodException("UriParser", "GetSyntax"); } var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" }); var setUpdatableFlagsMethod = uriParser.GetType().GetMethod("SetUpdatableFlags", BindingFlags.Instance | BindingFlags.NonPublic); if (setUpdatableFlagsMethod == null) { throw new MissingMethodException("UriParser", "SetUpdatableFlags"); } setUpdatableFlagsMethod.Invoke(uriParser, new object[] {0}); } 

这是我提出的一段时间的错误 。 它应该在4.0中修复,但我没有屏住呼吸。 显然它仍然是RC中的一个问题。

通过组合前面的2个答案,您可以使用一种方法,每个进程只需要调用一次,该工作在.net 4和.net 3.5上都有效。

 // System.UriSyntaxFlags is internal, so let's duplicate the flag privately private const int UnEscapeDotsAndSlashes = 0x2000000; private void LeaveDotsAndSlashesEscaped() { var getSyntaxMethod = typeof (UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic); if (getSyntaxMethod == null) { throw new MissingMethodException("UriParser", "GetSyntax"); } var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" }); FieldInfo flagsFieldInfo = typeof(UriParser).GetField("m_Flags", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.Instance); if (flagsFieldInfo == null) { throw new MissingFieldException("UriParser", "m_Flags"); } int flags = (int) flagsFieldInfo.GetValue(uriParser); // unset UnEscapeDotsAndSlashes flag and leave the others untouched flags = flags & ~UnEscapeDotsAndSlashes; flagsFieldInfo.SetValue(uriParser, flags); }