Uri.TryCreate抛出UriFormatException? [英] Uri.TryCreate throws UriFormatException?

查看:610
本文介绍了Uri.TryCreate抛出UriFormatException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个尝试创建一个开放的,然后清理的方法(删除碎片,不包括某些域和查询字符串模式等)。该方法是这样的:

I have a method that tries to create a Uri and then clean it up (removes fragments, excludes some domains and query string patterns, etc.). The method looks like this:

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);
}

该方法已被工作正常了几个月。但昨晚失败。 Uri.TryCreate()抛出一个异常!这里的堆栈跟踪:

This method has been working fine for months. But last night it failed. Uri.TryCreate() threw an exception! Here's the stack trace:

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)

文档 Uri.TryCreate(URI,字符串,出URI)表示,返回值是如果成功,否则,但它的沉默异常。然而,对于 Uri.TryCreate(URI,乌里,出URI)文件说:

Documentation for Uri.TryCreate(Uri, String, out Uri) says that the return value is True if successful, False otherwise, but it's silent about exceptions. However, documentation for Uri.TryCreate(Uri, Uri, out Uri) says:

此方法构造URI,看跌期权   它的规范形式,并验证   它。如果发生未处理的异常,   这种方法捕获它。如果你想   创建一个开放的,并得到异常使用   一个开放的构造函数。

This method constructs the URI, puts it in canonical form, and validates it. If an unhandled exception occurs, this method catches it. If you want to create a Uri and get exceptions use one of the Uri constructors.

堆栈跟踪显示异常被抛出 Uri.TryCreate(URI,乌里,出URI),其中,根据该文件,不应该发生。

The stack trace shows that the exception was thrown in Uri.TryCreate(Uri, Uri, out Uri), which, according to the documentation, shouldn't happen.

这是一种非常罕见的现象。我一直在使用code几个月,通过它的字面运行数十亿网址的,并没有遇到问题到现在。不幸的是,我不知道是什么东西的组合导致了问题。我希望建立一个测试用例,显示错误。

This is a very rare occurrence. I've been using that code for months, running literally billions of urls through it, and haven't encountered a problem until now. Unfortunately I don't know what combination of things caused the problem. I'm hoping to construct a test case that shows the error.

这是在 Uri.TryCreate 一个已知的bug,还是我失去了一些东西?

Is this a known bug in Uri.TryCreate, or am I missing something?

推荐答案

不愿等待潜在的几个月对我的code再遇到这种情况,我花了一些时间与ILDASM找出 TryCreate 在做什么,然后多一点时间想出一个方法来重现错误。

Unwilling to wait potentially several months for my code to encounter this situation again, I spent some time with ILDASM to figure out what TryCreate is doing, and then a little more time coming up with a way to reproduce the error.

Uri.TryCreate(URI基本URI,乌里relativeUri,出开放的结果)的原因崩溃似乎是一个格式错误基本URI 。例如,乌里构造函数允许以下内容:

The reason for the crash in Uri.TryCreate(Uri baseUri, Uri relativeUri, out Uri result) appears to be a badly formatted baseUri. For example, the Uri constructor allows the following:

Uri badUri = new Uri("mailto:test1@mischel.comtest2@mischel.com");

根据RFC为的mailto:URIs,它们不应该被允许。虽然构造函数创建并返回一个乌里对象,试图访问(部分),它的属性抛出 UriFormatException 。例如,给定上述code,这条线将抛出一个异常:

According to the RFC for mailto: URIs, that shouldn't be allowed. And although the constructor creates and returns a Uri object, trying to access (some of) its properties throws UriFormatException. For example, given the above code, this line will throw an exception:

string badUriString = badUri.AbsoluteUri;

我觉得最有趣的是,乌里类似乎使用两种不同的分析算法:内部一个结构时使用,另一个用于获取单个组件

I find it rather interesting that the Uri class appears to use two different parsing algorithms: one used during construction, and one used internally for getting the individual components.

通过这项无效乌里 TryCreate 将导致我在原来的问题中描述的异常。该 TryCreate 方法检查基本URI 参数,但没有(不能,我会想象),否则对其进行验证。它有假设,如果该参数不为null,传递的对象是完全初始化和有效的乌里实例。但在构建结果有些时候, TryCreate 试图获得基本URI ,并抛出一个异常的组件。

Passing this invalid Uri to TryCreate will result in the exception that I described in the original question. The TryCreate method checks the baseUri parameter for null, but doesn't (can't, I would imagine) validate it otherwise. It has to assume that, if the parameter is non-null, the passed object is a fully initialized and valid Uri instance. But at some point in constructing the result, TryCreate attempts to obtain the components of baseUri and an exception is thrown.

我不能说我的程序实际上遇到一个mailto:URL被格式化的这种方式。我可以较为肯定的说,虽然,一个无效的乌里目标是在我的程序崩溃的原因,只是因为从我的程序异常堆栈跟踪匹配从测试程序堆栈跟踪。简单地说,错误是在乌里构造函数(以及在 TryCreate 方法),允许无效乌里要创建。

I can't say that my program actually encountered a mailto: URL that was formatted this way. I can say with some degree of certainty, though, that an invalid Uri object was the cause of the crash in my program, simply because the exception stack trace from my program matches the stack trace from the test program. Simply put, the bug is in the Uri constructor (and also in the TryCreate methods) which allow the invalid Uri to be created.

您可以按照Microsoft Connect上 bug报告

You can follow the bug report on Microsoft Connect.

这篇关于Uri.TryCreate抛出UriFormatException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆