为什么Uri中的冒号“:”传递给Uri.MakeRelativeUri导致exception?

以下代码行给出了一个例外。 这是框架中的错误吗? 如果不是我可以采取什么方法呢?

它似乎是问题导致的“:”(冒号),但是我确实看到这样一个URI在生产网站上工作正常(即在现实世界中似乎是一个有效的URI)

Uri relativeUri = new Uri("http://test.com/asdf").MakeRelativeUri(new Uri("http://test.com/xx:yy")); // gives => System.UriFormatException: A relative URI cannot be created because the // 'uriString' parameter represents an absolute URI Uri relativeUri = new Uri("http://test.com/asdf").MakeRelativeUri(new Uri("http://test.com/xxyy")); // this works - removed the colon between the xx and yy 

PS。 具体来说,鉴于以上情况,我可以问一下,我可以使用什么.NET类/方法(注意我正在从Web解析HTML页面)来获取(a)页面URI和(b)HTML中的相对字符串HREF参数[例如,在这种情况下可能是“/ xx:yy”]并返回可用于寻址该资源的有效URI?

换句话说,我如何模仿浏览器的行为,该浏览器转换HREF和页面URI以生成用于在单击它时转到该资源的URI。

我认为这是一个错误。

RFC1738表示:在其他字符中) 可以保留用于方案中的特殊含义。 但是http方案不会在路径部分中保留它

 Within the  and  components, "/", ";", "?" are reserved. 

(不是: 。)

 hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ] 

所以, http://test.com/xx:yy是一个有效的URI。 较新的RFC3968同意:

 pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 

当然,相对于http://test.com/asdf ,生成的xx:yy将是绝对URI,而不是有效的相对URI:

 path-noscheme = segment-nz-nc *( "/" segment ) segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) ; non-zero-length segment without any colon ":" 

因此, MakeRelativeUri有权报告存在问题,但实际上它应该通过编码来自动修复它:在绝对URI中有效的%3A在相对URI的第一段中有效。

我通常会尝试避免MakeRelativeUri支持根相对URI,这些URI更容易提取并且没有这个问题( /xx:yy可以)。

冒号在URL中扮演特殊角色 – 例如表示端口,因此“保留”( 参见此处 )。

URL使用某些字符来定义其语法。 如果这些字符未在URL中的特殊角色中使用,则需要对它们进行编码

因此,结肠应该逃脱。

如果找到冒号,它会尝试将冒号后面的值解析为端口号,如果您没有提供有效的端口号,它将失败。 有关UriFormatException详细信息的类似问题和MSDN链接的示例,请参见此处 。