Uri.TryCreate抛出UriFormatException?

Jim*_*hel 12 .net c#

我有一个方法,尝试创建一个Uri,然后清理它(删除片段,排除一些域和查询字符串模式等).该方法如下所示:

static public bool TryCreateCleanUri(Uri baseUri, string relstr, out Uri result)
{
    if (!Uri.TryCreate(baseUri, relstr, out result))
    {
        return false;
    }
    return CleanupUri(result, out result);
}
Run Code Online (Sandbox Code Playgroud)

这种方法已经好几个月了.但是昨晚失败了.Uri.TryCreate()抛出异常!这是堆栈跟踪:

ERROR: Unhandled exception caught.  Program terminating.
System.UriFormatException: Invalid URI: The hostname could not be parsed.
   at System.Uri.CreateHostStringHelper(String str, UInt16 idx, UInt16 end, Flags& flags, String& scopeId)
   at System.Uri.CreateHostString()
   at System.Uri.GetComponentsHelper(UriComponents uriComponents, UriFormat uriFormat)
   at System.Uri.CombineUri(Uri basePart, String relativePart, UriFormat uriFormat)
   at System.Uri.GetCombinedString(Uri baseUri, String relativeStr, Boolean dontEscape, String& result)
   at System.Uri.ResolveHelper(Uri baseUri, Uri relativeUri, String& newUriString, Boolean& userEscaped, UriFormatException& e)
   at System.Uri.TryCreate(Uri baseUri, Uri relativeUri, Uri& result)
   at System.Uri.TryCreate(Uri baseUri, String relativeUri, Uri& result)
Run Code Online (Sandbox Code Playgroud)

文档Uri.TryCreate(Uri, String, out Uri)说明返回值True是否成功,False否则,但是它对异常没有提及.但是,文档Uri.TryCreate(Uri, Uri, out Uri)说:

此方法构造URI,将其置于规范形式,并对其进行验证.如果发生未处理的异常,则此方法捕获它.如果要创建Uri并获取异常,请使用其中一个Uri构造函数.

堆栈跟踪显示异常被抛出Uri.TryCreate(Uri, Uri, out Uri),根据文档,这不应该发生.

这种情况非常罕见.几个月来我一直在使用该代码,通过它运行数十亿个URL,直到现在才遇到问题.不幸的是我不知道是什么组合导致了这个问题.我希望构建一个显示错误的测试用例.

这是一个已知的错误Uri.TryCreate,还是我错过了什么?

Jim*_*hel 20

我不愿意等待几个月的时间让我的代码再次遇到这种情况,我花了一些时间与ILDASM一起弄清楚TryCreate正在做什么,然后又花了一点时间来重现错误.

崩溃的原因Uri.TryCreate(Uri baseUri, Uri relativeUri, out Uri result)似乎是格式错误baseUri.例如,Uri构造函数允许以下内容:

Uri badUri = new Uri("mailto:test1@mischel.comtest2@mischel.com");
Run Code Online (Sandbox Code Playgroud)

根据RFC for mailto:URIs,不应该允许.虽然构造函数创建并返回一个Uri对象,但尝试访问(某些)其属性会抛出UriFormatException.例如,给定上面的代码,此行将抛出异常:

string badUriString = badUri.AbsoluteUri;
Run Code Online (Sandbox Code Playgroud)

我觉得很有趣的是,Uri该类似乎使用了两种不同的解析算法:一种在构造过程中使用,另一种在内部用于获取各个组件.

通过这个无效Uri,以TryCreate将导致我在原来的问题中描述的异常.该TryCreate方法检查baseUri参数null,但不是(不能,我会想象)否则验证它.必须假设,如果参数为非null,则传递的对象是完全初始化且有效的Uri实例.但是在构造结果的某些时候,会TryCreate尝试获取组件baseUri和异常.

我不能说我的程序实际上遇到了mailto:这种格式化的URL.我可以肯定地说,Uri在我的程序中,无效对象是导致崩溃的原因,因为我的程序中的异常堆栈跟踪与测试程序中的堆栈跟踪相匹配.简单地说,错误在Uri构造函数(以及TryCreate方法中)中,允许Uri创建无效.

您可以按照Microsoft Connect上的错误报告进行操作.