C# URL有时编码不正确-线程问题?

C# URL有时编码不正确-线程问题?,c#,multithreading,C#,Multithreading,我正在使用C#开发一个Windows窗体应用程序,并且有一个类似于以下的方法,该方法由多个线程(确切地说,是由多个后台工作人员)访问: 我使用此方法使用一些必需的OAuth参数对任意URL进行签名,然后执行HttpWebRequest来检索内容 编辑1:以下是addOAuthParameter方法的内容: private Uri addOAuthParameters(string uri) { UriBuilder builder = new UriBuilder(uri); N

我正在使用C#开发一个Windows窗体应用程序,并且有一个类似于以下的方法,该方法由多个线程(确切地说,是由多个后台工作人员)访问:

我使用此方法使用一些必需的OAuth参数对任意URL进行签名,然后执行HttpWebRequest来检索内容

编辑1:以下是addOAuthParameter方法的内容:

private Uri addOAuthParameters(string uri)
{
    UriBuilder builder = new UriBuilder(uri);
    NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
    query.Set("oauth_signature_method", "PLAINTEXT");
    query.Set("oauth_timestamp", "" + (int)(DateTime.UtcNow -
        new DateTime(1970, 1, 1)).TotalSeconds);
    query.Set("oauth_nonce", "" + getNonce());
    query.Set("oauth_version", "1.0");
    builder.Query = query.ToString();
    return builder.Uri;
}
有时,oauth_签名参数包含一个符号and,尽管这应该由NameValueCollection对象用%26正确编码,因此,我得到一个“401 Unauthorized”。我觉得当多个后台工作人员(多线程?)访问该方法时会发生这种情况。可能吗

编辑2:好的,看来我已经缩小了问题的范围。如果我执行
Debug.Assert(builder.Uri.ToString().Contain(“%26”)和&builder.Uri.PathAndQuery.Contains(“%26”)
结果是
builder.Uri.ToString()
不包含%26,而
builder.Uri.PathAndQuery
包含。为什么

调试这个问题变得非常困难。有人有什么建议吗?

只用于显示返回未转义字符串的文档

您想要使用,或者

GetComponents的优点是转义是显式指定的,因此没有歧义

一些简单的建议(源于基思·布朗的博客文章)

  • 当您知道Uri是绝对值时,使用Uri.AbsoluteUri获取Uri的值
  • 当Uri可以是绝对值或相对值时,使用Uri.OriginalString获取Uri的值(此方法不会为相对Uri引发InvalidOperationException)
  • 使用Uri.ToString仅当您确实希望Uri的值不被替换时(例如,当您希望为人很好地显示它时)才获取Uri的值
  • 在调试器中查看URI时,请记住调试器使用URI.ToString,因此您看到的内容可能与URI包含的内容不完全匹配
仅用于显示文档状态,即返回未转义字符串

您想要使用,或者

GetComponents的优点是转义是显式指定的,因此没有歧义

一些简单的建议(源于基思·布朗的博客文章)

  • 当您知道Uri是绝对值时,使用Uri.AbsoluteUri获取Uri的值
  • 当Uri可以是绝对值或相对值时,使用Uri.OriginalString获取Uri的值(此方法不会为相对Uri引发InvalidOperationException)
  • 使用Uri.ToString仅当您确实希望Uri的值不被替换时(例如,当您希望为人很好地显示它时)才获取Uri的值
  • 在调试器中查看URI时,请记住调试器使用URI.ToString,因此您看到的内容可能与URI包含的内容不完全匹配

不,那不是线程。唯一被改变的对象是该方法调用的本地对象;它们似乎不在线程之间共享(例如,通过字段或可变类参数)?这些是否由其他线程/在其他函数中编辑?编辑:您能让我们看看您的addOAuthParameters(string)函数吗?consumerKey和ConsumerCret是包含该方法的对象的本地函数,从不从外部修改(它们是私有的)。我明天给你addOAuthParameters。不,那不是线程。唯一被改变的对象是该方法调用的本地对象;它们似乎不在线程之间共享(例如,通过字段或可变类参数)?这些是否由其他线程/在其他函数中编辑?编辑:您能让我们看看您的addOAuthParameters(string)函数吗?consumerKey和ConsumerCret是包含该方法的对象的本地函数,从不从外部修改(它们是私有的)。明天我会给你addOAuthParameters。太棒了,这很好。Uri接口确实令人困惑。非常感谢,先生!太棒了,这就很好了。Uri接口确实令人困惑。非常感谢,先生!
private Uri addOAuthParameters(string uri)
{
    UriBuilder builder = new UriBuilder(uri);
    NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
    query.Set("oauth_signature_method", "PLAINTEXT");
    query.Set("oauth_timestamp", "" + (int)(DateTime.UtcNow -
        new DateTime(1970, 1, 1)).TotalSeconds);
    query.Set("oauth_nonce", "" + getNonce());
    query.Set("oauth_version", "1.0");
    builder.Query = query.ToString();
    return builder.Uri;
}
var uri = new Uri("http://example.com/some?query=testing%26other");
Console.WriteLine(uri.ToString());
Console.WriteLine(uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped));

http://example.com/some?query=testing&other
/some?query=testing%26other