为什么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链接的示例,请参见此处 。